simple/
simple.rs

1use async_trait::async_trait;
2use std::error::Error;
3use std::time::Duration;
4use task_supervisor::{SupervisedTask, SupervisorBuilder, TaskError};
5
6#[derive(Clone)]
7struct MyTask {
8    pub emoji: char,
9}
10
11// A simple task that runs for 15 seconds, printing its status periodically.
12#[async_trait]
13impl SupervisedTask for MyTask {
14    async fn run(&mut self) -> Result<(), TaskError> {
15        for _ in 0..15 {
16            println!("{} Task is running!", self.emoji);
17            tokio::time::sleep(Duration::from_secs(1)).await;
18        }
19        println!("{} Task completed!", self.emoji);
20        Ok(())
21    }
22}
23
24#[tokio::main]
25async fn main() -> Result<(), Box<dyn Error>> {
26    // Build the supervisor with no initial tasks
27    let supervisor = SupervisorBuilder::default().build();
28
29    // Run the supervisor and get the handle
30    let handle = supervisor.run();
31
32    // Clone the handle for use in a separate task
33    let h = handle.clone();
34
35    // Spawn a task to manage and monitor the supervisor
36    tokio::spawn(async move {
37        // Add a new task after 5 seconds
38        tokio::time::sleep(Duration::from_secs(5)).await;
39        println!("Adding a task after 5 seconds...");
40        h.add_task("task1", MyTask { emoji: '🆕' })
41            .expect("Failed to add task");
42
43        // Check the status of the task after 2 seconds
44        tokio::time::sleep(Duration::from_secs(2)).await;
45        match h.get_task_status("task1").await {
46            Ok(Some(status)) => println!("Task 'task1' status: {status:?}"),
47            Ok(None) => println!("Task 'task1' not found"),
48            Err(e) => println!("Error getting task status: {e}"),
49        }
50
51        // Restart the task after 5 seconds
52        tokio::time::sleep(Duration::from_secs(5)).await;
53        println!("Restarting task after 5 seconds...");
54        h.restart("task1").expect("Failed to restart task");
55
56        // Check all task statuses after 2 seconds
57        tokio::time::sleep(Duration::from_secs(2)).await;
58        match h.get_all_task_statuses().await {
59            Ok(statuses) => {
60                println!("All task statuses:");
61                for (name, status) in statuses {
62                    println!("  {name}: {status:?}");
63                }
64            }
65            Err(e) => println!("Error getting all task statuses: {}", e),
66        }
67
68        // Kill the task after 5 seconds
69        tokio::time::sleep(Duration::from_secs(5)).await;
70        println!("Killing task after 5 seconds...");
71        h.kill_task("task1").expect("Failed to kill task");
72
73        // Check the status again after killing
74        tokio::time::sleep(Duration::from_secs(2)).await;
75        match h.get_task_status("task1").await {
76            Ok(Some(status)) => println!("Task 'task1' status after kill: {:?}", status),
77            Ok(None) => println!("Task 'task1' not found after kill"),
78            Err(e) => println!("Error getting task status after kill: {}", e),
79        }
80
81        // Shutdown the supervisor after 5 seconds
82        tokio::time::sleep(Duration::from_secs(5)).await;
83        println!("Shutting down supervisor...");
84        h.shutdown().expect("Failed to shutdown supervisor");
85    });
86
87    // Wait for the supervisor to complete
88    handle.wait().await?;
89    println!("All tasks died and supervisor shut down! 🫡");
90
91    Ok(())
92}