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}