use std::future::Future;
use futures::{
executor::ThreadPool,
future::RemoteHandle,
task::{SpawnError, SpawnExt},
};
use crate::prelude::*;
impl<T: 'static + Send> TaskHandle for RemoteHandle<Result<T, Infallible>> {
type Output = T;
type JoinError = Infallible;
fn join(self) -> impl Future<Output = Result<Self::Output, Self::JoinError>> {
self
}
fn abort(self) {}
async fn cancel(self) {}
fn detach(self) {
self.forget()
}
}
#[derive(Clone)]
pub struct Runtime {
thread_pool: ThreadPool,
}
impl From<futures::executor::ThreadPool> for Runtime {
fn from(thread_pool: ThreadPool) -> Self {
Self { thread_pool }
}
}
impl TaskInterface for Runtime {
type TaskHandle<T: 'static + Send> = RemoteHandle<Result<T, Self::JoinError>>;
type SpawnError = SpawnError;
type JoinError = Infallible;
fn spawn_task<F, T>(
&self,
future: F,
) -> Result<crate::utils::TaskHandle<Self::TaskHandle<F::Output>>, Self::SpawnError>
where
F: Future<Output = T> + Send + 'static,
T: Send + 'static,
{
self.thread_pool
.spawn_with_handle(async { Ok(future.await) })
.map(|x| x.into())
}
fn block_on<F: Future>(&self, future: F) -> F::Output {
futures::executor::block_on(future)
}
}
impl CreationInterface for Runtime {
type NewError = std::io::Error;
fn new(config: Config) -> Result<Self, Self::NewError> {
let mut thread_pool_builder = ThreadPool::builder();
if let Some(prefix) = config.prefix {
thread_pool_builder.name_prefix(prefix);
}
if let Some(thread_count) = config.thread_count {
thread_pool_builder.pool_size(thread_count);
}
Ok(Self {
thread_pool: thread_pool_builder.create()?,
})
}
}