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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
//! # taskvisor
//!
//! Taskvisor is an in-process Tokio task supervisor with retries, reliable outcomes, and keyed queue/replace/reject admission.
//! It can time out attempts, stop tasks during shutdown, and dynamically manage work.
//!
//! Use it for dynamic or keyed background work that needs conflict handling and 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 a configured controller, 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`], [`TaskOutcomeKind`] |
//! | Admit keyed work | [`ControllerSpec`], [`PreparedSubmission`], [`AdmissionPolicy`], [`ControllerConfig`] |
//! | 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`].
//!
//! ## Keyed Admission
//!
//! The default `controller` feature provides per-slot admission. Configure it with
//! [`SupervisorBuilder::with_controller`], then submit a [`ControllerSpec`] that
//! queues, replaces, or rejects work when the slot already has an owner.
//! Different slots are independent, subject to the supervisor's global limits.
//!
//! ## Feature Flags
//!
//! - `tracing`: forwards lifecycle events to `tracing`.
//! - `logging`: simple event logging for examples and development.
//! - `tokio-util-interop`: exposes the underlying Tokio cancellation token.
//! - `controller` (default): slot-based admission with queue, replace, and reject rules.
//! - `test-util`: constructors for task contexts, identities, and outcomes in tests.
//!
//! ## Examples
//!
//! Choose a short path, or [browse all examples on GitHub](https://github.com/soltiHQ/taskvisor/tree/main/examples):
//!
//! - New to supervision: `basic` → `worker` → `outcomes`.
//! - Need per-key coordination: `tenant_sync` → `slots` → `admission`.
//!
//! ### Start here
//!
//! | 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 restart rules under one supervisor |
//!
//! ### Real patterns
//!
//! | Example | What it shows |
//! |---------------------------------------------------------------------------------------------|-----------------------------------------------------------------|
//! | [queue_consumer](https://github.com/soltiHQ/taskvisor/blob/main/examples/queue_consumer.rs) | Retry a failed broker connection |
//! | [cpu_job](https://github.com/soltiHQ/taskvisor/blob/main/examples/cpu_job.rs) | Run CPU-heavy work on rayon without blocking Tokio |
//!
//! ### Observability
//!
//! | Example | What it shows |
//! |-----------------------------------------------------------------------------------------|-----------------------------------------------------------|
//! | [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 events into `tracing` (feature `tracing`) |
//! | [metrics](https://github.com/soltiHQ/taskvisor/blob/main/examples/metrics.rs) | Build Prometheus counters from lifecycle events |
//!
//! ### Dynamic work and outcomes
//!
//! | Example | What it shows |
//! |-----------------------------------------------------------------------------------------|----------------------------------------------------------|
//! | [dynamic](https://github.com/soltiHQ/taskvisor/blob/main/examples/dynamic.rs) | Add, list, cancel, and remove tasks at runtime |
//! | [outcomes](https://github.com/soltiHQ/taskvisor/blob/main/examples/outcomes.rs) | Wait for reliable outcomes, including a timeout |
//!
//! ### Keyed admission
//!
//! | Example | What it shows |
//! |-----------------------------------------------------------------------------------------------|-------------------------------------------------------|
//! | [tenant_sync](https://github.com/soltiHQ/taskvisor/blob/main/examples/tenant_sync.rs) | Keep only the latest sync revision per tenant |
//! | [slots](https://github.com/soltiHQ/taskvisor/blob/main/examples/slots.rs) | Compare queue, replace, and reject policies |
//! | [admission](https://github.com/soltiHQ/taskvisor/blob/main/examples/admission.rs) | Observe typed admission and rejection outcomes |
/// 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
pub use ;
pub use LogWriter;
pub use TracingBridge;