Skip to main content

taskvisor/
lib.rs

1//! # taskvisor
2//!
3//! **Taskvisor** is a lightweight task orchestration library for Rust.
4//!
5//! It provides primitives to define, supervise, and restart async tasks
6//! with configurable policies. The crate is designed as a building block
7//! for higher-level orchestrators and agents.
8//!
9//! ## Architecture
10//! ### Overview
11//!
12//! ```text
13//!     ┌──────────────┐   ┌──────────────┐   ┌──────────────┐
14//!     │   TaskSpec   │   │   TaskSpec   │   │   TaskSpec   │
15//!     │(user task #1)│   │(user task #2)│   │(user task #3)│
16//!     └──────┬───────┘   └──────┬───────┘   └──────┬───────┘
17//!            ▼                  ▼                  ▼
18//! ┌───────────────────────────────────────────────────────────────────┐
19//! │  Supervisor (runtime orchestrator)                                │
20//! │  - Bus (broadcast events)                                         │
21//! │  - AliveTracker (tracks task state with sequence numbers)         │
22//! │  - SubscriberSet (fans out to user subscribers)                   │
23//! │  - Registry (manages active tasks by name)                        │
24//! └──────┬──────────────────┬──────────────────┬───────────────┬──────┘
25//!        ▼                  ▼                  ▼               │
26//!     ┌──────────────┐   ┌──────────────┐   ┌──────────────┐   │
27//!     │  TaskActor   │   │  TaskActor   │   │  TaskActor   │   │
28//!     │ (retry loop) │   │ (retry loop) │   │ (retry loop) │   │
29//!     └┬─────────────┘   └┬─────────────┘   └┬─────────────┘   │
30//!      │                  │                  │                 │
31//!      │ Publishes        │ Publishes        │ Publishes       │
32//!      │ Events:          │ Events:          │ Events:         │
33//!      │ - TaskStarting   │ - TaskStarting   │ - TaskStarting  │
34//!      │ - TaskFailed     │ - TaskStopped    │ - TimeoutHit    │
35//!      │ - BackoffSched.  │ - ActorExhausted │ - ...           │
36//!      │                  │                  │                 │
37//!      ▼                  ▼                  ▼                 ▼
38//! ┌───────────────────────────────────────────────────────────────────┐
39//! │                        Bus (broadcast channel)                    │
40//! │              (capacity: SupervisorConfig::bus_capacity)           │
41//! └─────────────────────────────────┬─────────────────────────────────┘
42//!                                   ▼
43//!                       ┌────────────────────────┐
44//!                       │  subscriber_listener   │
45//!                       │   (in Supervisor)      │
46//!                       └───┬────────────────┬───┘
47//!                           ▼                ▼
48//!                    AliveTracker     SubscriberSet
49//!                  (sequence-based)   (per-sub queues)
50//!                                  ┌─────────┼─────────┐
51//!                                  ▼         ▼         ▼
52//!                                  worker1  worker2  workerN
53//!                                  ▼         ▼         ▼
54//!                             sub1.on   sub2.on   subN.on
55//!                              _event()  _event()  _event()
56//! ```
57//!
58//! ### Lifecycle
59//!
60//! ```text
61//! TaskSpec ──► Supervisor ──► Registry ──► TaskActor::run()
62//!
63//! loop {
64//!   ├─► attempt += 1
65//!   ├─► acquire semaphore (optional, cancellable)
66//!   ├─► publish TaskStarting{ task, attempt }
67//!   ├─► run_once(task, timeout, attempt)
68//!   │       │
69//!   │       ├─ Ok  ──► publish TaskStopped
70//!   │       │          ├─ RestartPolicy::Never     ─► ActorExhausted, exit
71//!   │       │          ├─ RestartPolicy::OnFailure ─► ActorExhausted, exit
72//!   │       │          └─ RestartPolicy::Always    ─► reset delay, continue
73//!   │       │
74//!   │       └─ Err ──► publish TaskFailed{ task, error, attempt }
75//!   │                  ├─ RestartPolicy::Never     ─► ActorExhausted, exit
76//!   │                  └─ RestartPolicy::OnFailure/Always:
77//!   │                       ├─ compute delay = backoff.next(backoff_attempt)
78//!   │                       ├─ publish BackoffScheduled{ delay, attempt }
79//!   │                       ├─ sleep(delay) (cancellable)
80//!   │                       └─ continue
81//!   │
82//!   └─ exit conditions:
83//!        - runtime_token cancelled (OS signal or explicit remove)
84//!        - RestartPolicy forbids continuation ─► ActorExhausted
85//!        - Fatal error ─► ActorDead
86//!        - semaphore closed
87//! }
88//!
89//! On exit: actor cleanup removes from Registry (if PolicyExhausted/Fatal)
90//! ```
91//!
92//! ## Features
93//!
94//! | Area              | Description                                                            | Key types / traits                     |
95//! |-------------------|------------------------------------------------------------------------|----------------------------------------|
96//! | **Subscriber API**| Hook into task lifecycle events (logging, metrics, custom subscribers).| [`Subscribe`]                          |
97//! | **Policies**      | Configure restart/backoff strategies for tasks.                        | [`RestartPolicy`], [`BackoffPolicy`]   |
98//! | **Supervision**   | Manage groups of tasks and their lifecycle.                            | [`Supervisor`], [`SupervisorHandle`]   |
99//! | **Errors**        | Typed errors for orchestration and task execution.                     | [`TaskError`], [`RuntimeError`]        |
100//! | **Tasks**         | Define tasks as functions or specs, easy to compose and run.           | [`TaskRef`], [`TaskFn`], [`TaskSpec`]  |
101//! | **Configuration** | Centralize runtime settings.                                           | [`SupervisorConfig`]                   |
102//!
103//! ## Optional features
104//!
105//! - `logging`: exports a simple built-in [`LogWriter`] _(demo/reference only)_.
106//! - `controller`:  exposes controller runtime and admission types.
107//!
108//! ## Example
109//!
110//! ```rust
111//! use taskvisor::prelude::*;
112//!
113//! #[tokio::main(flavor = "current_thread")]
114//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
115//!     let sup = Supervisor::new(SupervisorConfig::default(), vec![]);
116//!
117//!     // Define a simple task that runs once and exits
118//!     let hello: TaskRef = TaskFn::arc("hello", |ctx: CancellationToken| async move {
119//!         if ctx.is_cancelled() { return Ok(()); }
120//!         println!("Hello from task!");
121//!         Ok(())
122//!     });
123//!
124//!     // One-shot task (runs once, never restarts)
125//!     let spec = TaskSpec::once(hello);
126//!
127//!     sup.run(vec![spec]).await?;
128//!     Ok(())
129//! }
130//! ```
131
132pub mod prelude;
133
134mod core;
135pub use core::{Supervisor, SupervisorConfig, SupervisorHandle};
136
137mod tasks;
138pub use tasks::{BoxTaskFuture, Task, TaskFn, TaskRef, TaskSpec};
139
140mod policies;
141pub use policies::{BackoffPolicy, JitterPolicy, RestartPolicy};
142
143mod events;
144pub use events::{BackoffSource, Event, EventKind};
145
146mod error;
147pub use error::{RuntimeError, TaskError};
148
149mod subscribers;
150pub use subscribers::Subscribe;
151
152#[cfg(feature = "controller")]
153mod controller;
154#[cfg(feature = "controller")]
155pub use controller::{AdmissionPolicy, ControllerConfig, ControllerError, ControllerSpec};
156
157#[cfg(feature = "logging")]
158pub use subscribers::LogWriter;