1use std::future::Future;
4
5use tokio::task::JoinHandle;
6use tokio_util::{sync::CancellationToken, task::TaskTracker};
7use tracing::info;
8
9#[derive(Clone, Default)]
11pub struct TaskExecutor {
12 token: CancellationToken,
13 tracker: TaskTracker,
14}
15
16impl TaskExecutor {
17 pub fn new() -> Self {
19 Self::default()
20 }
21
22 pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output>
24 where
25 F: Future + Send + 'static,
26 F::Output: Send + 'static,
27 {
28 self.tracker.spawn(future)
29 }
30
31 pub fn cancellation_token(&self) -> CancellationToken {
33 self.token.clone()
34 }
35
36 pub fn trigger_shutdown(&self) {
38 if !self.token.is_cancelled() {
39 info!("Shutting down...");
40 }
41 self.token.cancel();
42 }
43
44 pub async fn wait_for_shutdown(&self) {
46 self.token.cancelled().await;
47 self.tracker.close();
48 self.tracker.wait().await;
49 }
50}