stratum_apps/
task_manager.rs

1use std::sync::Mutex as StdMutex;
2use tokio::task::JoinHandle;
3
4/// Manages a collection of spawned tokio tasks.
5///
6/// This struct provides a centralized way to spawn, track, and manage the lifecycle
7/// of async tasks in the translator. It maintains a list of join handles that can
8/// be used to wait for all tasks to complete or abort them during shutdown.
9pub struct TaskManager {
10    tasks: StdMutex<Vec<JoinHandle<()>>>,
11}
12
13impl Default for TaskManager {
14    fn default() -> Self {
15        Self::new()
16    }
17}
18
19impl TaskManager {
20    /// Creates a new TaskManager instance.
21    ///
22    /// Initializes an empty task manager ready to spawn and track tasks.
23    pub fn new() -> Self {
24        Self {
25            tasks: StdMutex::new(Vec::new()),
26        }
27    }
28
29    /// Spawns a new async task and adds it to the managed collection.
30    ///
31    /// The task will be tracked by this manager and can be waited for or aborted
32    /// using the other methods.
33    ///
34    /// # Arguments
35    /// * `fut` - The future to spawn as a task
36    #[track_caller]
37    pub fn spawn<F>(&self, fut: F)
38    where
39        F: std::future::Future<Output = ()> + Send + 'static,
40    {
41        use tracing::Instrument;
42        let location = std::panic::Location::caller();
43        let span = tracing::trace_span!(
44            "task",
45            file = location.file(),
46            line = location.line(),
47            column = location.column(),
48        );
49
50        let handle = tokio::spawn(fut.instrument(span));
51        self.tasks.lock().unwrap().push(handle);
52    }
53
54    /// Waits for all managed tasks to complete.
55    ///
56    /// This method will block until all tasks that were spawned through this
57    /// manager have finished executing. Tasks are joined in reverse order
58    /// (most recently spawned first).
59    pub async fn join_all(&self) {
60        let handles = {
61            let mut tasks = self.tasks.lock().unwrap();
62            std::mem::take(&mut *tasks)
63        };
64
65        for handle in handles {
66            let _ = handle.await;
67        }
68    }
69
70    /// Aborts all managed tasks.
71    ///
72    /// This method immediately cancels all tasks that were spawned through this
73    /// manager. The tasks will be terminated without waiting for them to complete.
74    pub async fn abort_all(&self) {
75        let mut tasks = self.tasks.lock().unwrap();
76        for handle in tasks.drain(..) {
77            handle.abort();
78        }
79    }
80}