1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
//! # taskvisor
//!
//! Taskvisor supervises long-running Tokio tasks.
//! It can restart failed work, slow down retries, time out each attempt, and stop tasks during shutdown.
//!
//! Use it for workers, consumers, connection loops, and other background work that should have a clear lifecycle.
//!
//! ## Start Here
//!
//! 1. Create a [`Task`] with [`TaskFn`] or your own type.
//! 2. Wrap it in a [`TaskSpec`] to choose restart rules.
//! 3. Start a [`Supervisor`] in static or dynamic mode.
//! 4. Make long-running tasks listen to [`TaskContext`] cancellation.
//!
//! ```text
//! TaskFn or impl Task
//! ▼
//! TaskSpec ── fills missing values from ──► TaskDefaults
//! ▼
//! Supervisor
//! │ │
//! │ └── best-effort events ──► Subscribe
//! │
//! └── watched final result ────────► TaskWaiter
//! ```
//!
//! ## Choose a Mode
//!
//! - **Static:** call [`Supervisor::run`] with a known task set.
//! It waits for all tasks to finish or for an OS shutdown signal.
//! - **Dynamic:** call [`Supervisor::serve`].
//! It returns a [`SupervisorHandle`] that can add, remove, cancel, and list tasks while the service is running.
//!
//! `run` registers its initial task list as one batch.
//! If a name is repeated or already in use, no task from that batch starts.
//!
//! ## One Task, Many Attempts
//!
//! A registered task has one [`TaskId`], but it may run several attempts:
//!
//! ```text
//! register
//! ▼
//! attempt 1 ── failure ──► backoff ──► attempt 2 ── success ──► finish
//! ▼
//! TaskOutcome
//! ```
//!
//! Attempts for one task never overlap.
//! [`RestartPolicy`] decides whether a new attempt is allowed.
//! [`BackoffPolicy`] sets the delay after a retryable failure.
//! A timeout applies to one attempt, not to the full task lifetime.
//!
//! ## Cancellation and Shutdown
//!
//! Cancellation is cooperative first.
//! A long-running task should await [`TaskContext::cancelled`] or use [`TaskContext::run_until_cancelled`], then return [`TaskError::Canceled`].
//! During shutdown, taskvisor waits for the configured grace period.
//! It aborts tasks that still have not stopped.
//!
//! Dropping one supervisor or handle clone does not stop the runtime.
//! Dropping the last public owner sends best-effort cancellation, but cannot wait for cleanup.
//! Call [`SupervisorHandle::shutdown`] when cleanup must be complete before your code continues.
//!
//! ## Events or Final Outcomes?
//!
//! Lifecycle [`Event`] values are **best-effort**.
//! They are suitable for logs, metrics, and live status.
//! A slow subscriber can miss events.
//!
//! A [`TaskWaiter`] uses a direct completion channel.
//! Event-bus lag does not affect it.
//!
//! It normally returns the final [`TaskOutcome`] after retries and registry cleanup;
//! it returns a runtime error if the completion channel closes first.
//!
//! Create one with [`SupervisorHandle::add_and_watch`] or its fail-fast `try_*` form.
//! With the `controller` feature, use `submit_and_watch` or `try_submit_and_watch`.
//!
//! ## Quick Start
//!
//! ```rust
//! use taskvisor::prelude::*;
//!
//! #[tokio::main(flavor = "current_thread")]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let supervisor = Supervisor::new(SupervisorConfig::default(), vec![]);
//!
//! let hello: TaskRef = TaskFn::arc("hello", |_ctx| async move {
//! println!("hello from taskvisor");
//! Ok(())
//! });
//!
//! supervisor.run(vec![TaskSpec::once(hello)]).await?;
//! Ok(())
//! }
//! ```
//!
//! ## Main Types
//!
//! | Need | Types |
//! |------------------|--------------------------------------------------------|
//! | Define work | [`Task`], [`TaskFn`], [`TaskContext`], [`TaskSpec`] |
//! | Run work | [`Supervisor`], [`SupervisorHandle`] |
//! | Set defaults | [`SupervisorConfig`], [`TaskDefaults`] |
//! | Control retries | [`RestartPolicy`], [`BackoffPolicy`], [`JitterPolicy`] |
//! | Observe progress | [`Event`], [`EventKind`], [`Subscribe`] |
//! | Wait for the end | [`TaskWaiter`], [`TaskOutcome`] |
//! | Handle errors | [`Error`], [`TaskError`], [`RuntimeError`] |
//!
//! Main types are re-exported at the crate root.
//! The module pages explain each area in more detail:
//! [`tasks`], [`policies`], [`events`], [`subscribers`], [`core`], and [`identity`].
//!
//! ## Optional Features
//!
//! - `tracing`: forwards lifecycle events to `tracing`.
//! - `logging`: simple event logging for examples and development.
//! - `tokio-util-interop`: exposes the underlying Tokio cancellation token.
//! - `controller`: slot-based admission with queue, replace, and reject rules.
//! - `test-util`: constructors for task contexts, identities, and outcomes in tests.
//!
//! ## Examples
//!
//! Repository examples go from simple to advanced ([browse them on GitHub](https://github.com/soltiHQ/taskvisor/tree/main/examples)):
//!
//! | Example | What it shows |
//! |---------------------------------------------------------------------------------------------|-------------------------------------------------------------------|
//! | [basic](https://github.com/soltiHQ/taskvisor/blob/main/examples/basic.rs) | Run one task and exit — the minimal wiring |
//! | [worker](https://github.com/soltiHQ/taskvisor/blob/main/examples/worker.rs) | A long-running worker that stops cleanly on Ctrl+C |
//! | [periodic](https://github.com/soltiHQ/taskvisor/blob/main/examples/periodic.rs) | Repeat a job after each successful cycle |
//! | [multiple](https://github.com/soltiHQ/taskvisor/blob/main/examples/multiple.rs) | Several tasks with different restart rules under one supervisor |
//! | [queue_consumer](https://github.com/soltiHQ/taskvisor/blob/main/examples/queue_consumer.rs) | A message consumer that reconnects after failures |
//! | [cpu_job](https://github.com/soltiHQ/taskvisor/blob/main/examples/cpu_job.rs) | Run CPU-heavy work on rayon, supervised, without blocking Tokio |
//! | [subscriber](https://github.com/soltiHQ/taskvisor/blob/main/examples/subscriber.rs) | React to lifecycle events with your own handler |
//! | [tracing](https://github.com/soltiHQ/taskvisor/blob/main/examples/tracing.rs) | Send supervisor events into your logs (feature `tracing`) |
//! | [metrics](https://github.com/soltiHQ/taskvisor/blob/main/examples/metrics.rs) | Count lifecycle events as Prometheus metrics |
//! | [dynamic](https://github.com/soltiHQ/taskvisor/blob/main/examples/dynamic.rs) | Add, cancel, and remove tasks while the app is running |
//! | [outcomes](https://github.com/soltiHQ/taskvisor/blob/main/examples/outcomes.rs) | Wait for a task's final result: done, failed, or canceled |
//! | [slots](https://github.com/soltiHQ/taskvisor/blob/main/examples/slots.rs) | Limit concurrency per slot: queue, replace, or drop the newcomer |
//! | [admission](https://github.com/soltiHQ/taskvisor/blob/main/examples/admission.rs) | Find out if your submission ran or was rejected |
/// Compiles runnable Rust code blocks in `README.md` as doctests.
;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use Subscribe;
pub use TaskId;
pub use ;
pub use LogWriter;
pub use TracingBridge;