Skip to main content

task_supervisor/
lib.rs

1//! # task-supervisor
2//!
3//! [![Crates.io](https://img.shields.io/crates/v/supervisor.svg)](https://crates.io/crates/task-supervisor)
4//! [![Docs.rs](https://docs.rs/supervisor/badge.svg)](https://docs.rs/task-supervisor)
5//!
6//! `task-supervisor` helps you keep Tokio tasks alive.
7//! It watches each task, restarts it if it crashes or stops responding, and lets you add, restart, or kill tasks at runtime.
8//!
9//! ## Install
10//!
11//! ```bash
12//! cargo add task-supervisor
13//! ```
14//!
15//! ## Quick example
16//!
17//! ```rust,no_run
18//! use task_supervisor::{SupervisorBuilder, SupervisedTask, TaskResult};
19//!
20//! #[derive(Clone)]
21//! struct Printer;
22//!
23//! impl SupervisedTask for Printer {
24//!     async fn run(&mut self) -> TaskResult {
25//!         println!("hello");
26//!         Ok(())
27//!     }
28//! }
29//!
30//! #[tokio::main]
31//! async fn main() {
32//!     let supervisor = SupervisorBuilder::default()
33//!         .with_task("printer", Printer)
34//!         .build()
35//!         .run();
36//!
37//!     supervisor.wait().await.unwrap();   // wait until every task finishes or is killed
38//! }
39//! ```
40//!
41//! ## What you get
42//!
43//! * **Automatic restarts** – failed tasks are relaunched with exponential back-off.
44//! * **Dynamic control** – add, restart, kill, or query tasks at runtime through a [`SupervisorHandle`].
45//! * **Configurable** – health-check interval, restart limits, back-off, dead-task threshold.
46//!
47//! ## Usage
48//!
49//! Build a supervisor with [`SupervisorBuilder`], call [`.build()`](SupervisorBuilder::build)
50//! to get a [`Supervisor`], then [`.run()`](Supervisor::run) to start it. This returns a
51//! [`SupervisorHandle`] you use to control things at runtime:
52//!
53//! | Method                          | Description                                          |
54//! | ------------------------------- | ---------------------------------------------------- |
55//! | `wait().await`                  | Block until the supervisor exits                     |
56//! | `add_task(name, task)`          | Register and start a new task                        |
57//! | `restart(name)`                 | Force-restart a task                                 |
58//! | `kill_task(name)`               | Stop a task permanently                              |
59//! | `get_task_status(name).await`   | Get a task's [`TaskStatus`]                          |
60//! | `get_all_task_statuses().await` | Get every task's status                              |
61//! | `shutdown()`                    | Stop all tasks and exit                              |
62//!
63//! The handle auto-shuts down the supervisor when all clones are dropped.
64//!
65//! ## Clone and restart behaviour
66//!
67//! Every task must implement `Clone`. The supervisor stores the **original**
68//! instance and clones it each time the task is started or restarted.
69//! Mutations made through `&mut self` in [`SupervisedTask::run`] only affect
70//! the running clone and are lost on restart.
71//!
72//! To share state across restarts, wrap it in an `Arc` (e.g. `Arc<AtomicUsize>`).
73//! Plain owned fields will always start from their original value. See the
74//! [`SupervisedTask`] docs for a full example.
75//!
76//! ## License
77//!
78//! [MIT](./LICENSE)
79
80pub use supervisor::{
81    builder::SupervisorBuilder,
82    handle::{SupervisorHandle, SupervisorHandleError},
83    Supervisor, SupervisorError,
84};
85pub use task::{SupervisedTask, TaskError, TaskResult, TaskStatus};
86
87mod supervisor;
88mod task;
89
90pub type TaskName = String;