use async_trait::async_trait;
use std::future::Future;
#[async_trait(?Send)]
pub trait TaskProvider: Clone {
fn spawn_task<F>(&self, name: &str, future: F) -> tokio::task::JoinHandle<()>
where
F: Future<Output = ()> + 'static;
async fn yield_now(&self);
}
#[derive(Clone, Debug)]
pub struct TokioTaskProvider;
#[async_trait(?Send)]
impl TaskProvider for TokioTaskProvider {
fn spawn_task<F>(&self, name: &str, future: F) -> tokio::task::JoinHandle<()>
where
F: Future<Output = ()> + 'static,
{
let task_name = name.to_string();
let task_name_clone = task_name.clone();
tokio::task::Builder::new()
.name(&task_name)
.spawn_local(async move {
tracing::trace!("Task {} starting", task_name_clone);
future.await;
tracing::trace!("Task {} completed", task_name_clone);
})
.expect("Failed to spawn task")
}
async fn yield_now(&self) {
tokio::task::yield_now().await;
}
}