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;