use std::future::Future;
pub trait AsyncExecutor {
fn execute<F, T>(&self, future: F) -> T
where
F: Future<Output = T> + Send + 'static,
T: Send + 'static;
}
pub struct DirectExecutor;
impl AsyncExecutor for DirectExecutor {
fn execute<F, T>(&self, future: F) -> T
where
F: Future<Output = T> + Send + 'static,
T: Send + 'static,
{
let handle = tokio::runtime::Handle::current();
let task = handle.spawn(future);
tokio::task::block_in_place(move || handle.block_on(task).expect("task panicked"))
}
}
pub struct BlockingExecutor {
rt: tokio::runtime::Runtime,
}
impl Default for BlockingExecutor {
fn default() -> Self {
Self::new()
}
}
impl BlockingExecutor {
pub fn new() -> Self {
Self {
rt: tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap(),
}
}
}
impl AsyncExecutor for BlockingExecutor {
fn execute<F, T>(&self, future: F) -> T
where
F: Future<Output = T> + Send + 'static,
T: Send + 'static,
{
self.rt.block_on(future)
}
}