moonpool_core/
task.rs

1//! Task spawning abstraction for single-threaded simulation environments.
2//!
3//! This module provides task provider abstractions for spawning local tasks
4//! that work with both simulation and real Tokio execution.
5
6use async_trait::async_trait;
7use std::future::Future;
8
9/// Provider for spawning local tasks in single-threaded context.
10///
11/// This trait abstracts task spawning to enable both real tokio tasks
12/// and simulation-controlled task scheduling while maintaining
13/// deterministic execution in single-threaded environments.
14#[async_trait(?Send)]
15pub trait TaskProvider: Clone {
16    /// Spawn a named task that runs on the current thread.
17    ///
18    /// The task will be executed using spawn_local to maintain
19    /// single-threaded execution guarantees required for simulation.
20    fn spawn_task<F>(&self, name: &str, future: F) -> tokio::task::JoinHandle<()>
21    where
22        F: Future<Output = ()> + 'static;
23
24    /// Yield control to allow other tasks to run.
25    ///
26    /// This is equivalent to tokio::task::yield_now() but abstracted
27    /// to enable simulation control and deterministic behavior.
28    async fn yield_now(&self);
29}
30
31/// Tokio-based task provider using spawn_local for single-threaded execution.
32///
33/// This provider creates tasks that run on the current thread using tokio's
34/// spawn_local mechanism, ensuring compatibility with simulation environments
35/// that require deterministic single-threaded execution.
36#[derive(Clone, Debug)]
37pub struct TokioTaskProvider;
38
39#[async_trait(?Send)]
40impl TaskProvider for TokioTaskProvider {
41    fn spawn_task<F>(&self, name: &str, future: F) -> tokio::task::JoinHandle<()>
42    where
43        F: Future<Output = ()> + 'static,
44    {
45        let task_name = name.to_string();
46        let task_name_clone = task_name.clone();
47        tokio::task::Builder::new()
48            .name(&task_name)
49            .spawn_local(async move {
50                tracing::trace!("Task {} starting", task_name_clone);
51                future.await;
52                tracing::trace!("Task {} completed", task_name_clone);
53            })
54            .expect("Failed to spawn task")
55    }
56
57    async fn yield_now(&self) {
58        tokio::task::yield_now().await;
59    }
60}