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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
//! # Taskvisor
//!
//! Taskvisor supervises in-process Tokio tasks that need retries, cancellation, final outcomes, or coordinated shutdown.
//! Its optional controller applies queue, replace, or reject policy per application key. Supervisor-wide limits still apply.
//!
//! ## Check the fit
//!
//! Taskvisor is useful when an application needs one or more of these:
//!
//! - tasks are added, removed, or watched while the service is running;
//! - task attempts need timeouts, retry limits, or backoff;
//! - application logic needs the final outcome of one submitted task;
//! - competing work for the same key must queue, replace older work, or be rejected.
//!
//! Taskvisor is not a persistent job queue. Runtime state, queued submissions, and task IDs
//! do not survive process exit. Use durable external storage when work must resume after a restart.
//!
//! ## Quick start
//!
//! A [`TaskFn`] turns an async closure into supervised work.
//! A [`TaskSpec`] gives that work a name and selects its lifecycle.
//!
//! ```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 = TaskFn::arc(|_ctx| async {
//! println!("hello from Taskvisor");
//! Ok(())
//! });
//!
//! supervisor
//! .run(vec![TaskSpec::once("hello", hello)])
//! .await?;
//! Ok(())
//! }
//! ```
//!
//! [`Supervisor::run`] accepts the complete static batch or rejects it.
//! The method returns after the shared cleanup workflow, not with each task's outcome.
//! Use a watched dynamic add when application logic needs that result.
//!
//! ## Continue with a runnable example
//!
//! The [user guide] explains the application workflow from task definition through production boundaries.
//! The [examples guide] includes the learning path, commands, feature flags, and stop behavior.
//!
//! - Foundations: [basic], [task type], [graceful worker], [application shutdown], [periodic],
//! [restart policies], and [configuration].
//! - Runtime patterns: [outcomes], [dynamic tasks], [queue consumer], and [CPU job].
//! - Observability: [custom subscriber], [logging], [tracing], and [metrics].
//! - Keyed admission: [controller slots], [controller admission], and [tenant sync].
//!
//! [user guide]: https://github.com/soltiHQ/taskvisor/blob/main/guide.md
//! [examples guide]: https://github.com/soltiHQ/taskvisor/blob/main/examples/README.md
//! [basic]: https://github.com/soltiHQ/taskvisor/blob/main/examples/basic.rs
//! [task type]: https://github.com/soltiHQ/taskvisor/blob/main/examples/task_type.rs
//! [graceful worker]: https://github.com/soltiHQ/taskvisor/blob/main/examples/graceful_worker.rs
//! [application shutdown]: https://github.com/soltiHQ/taskvisor/blob/main/examples/application_shutdown.rs
//! [periodic]: https://github.com/soltiHQ/taskvisor/blob/main/examples/periodic.rs
//! [restart policies]: https://github.com/soltiHQ/taskvisor/blob/main/examples/restart_policies.rs
//! [configuration]: https://github.com/soltiHQ/taskvisor/blob/main/examples/configuration.rs
//! [outcomes]: https://github.com/soltiHQ/taskvisor/blob/main/examples/outcomes.rs
//! [dynamic tasks]: https://github.com/soltiHQ/taskvisor/blob/main/examples/dynamic_tasks.rs
//! [queue consumer]: https://github.com/soltiHQ/taskvisor/blob/main/examples/queue_consumer.rs
//! [CPU job]: https://github.com/soltiHQ/taskvisor/blob/main/examples/cpu_job.rs
//! [custom subscriber]: https://github.com/soltiHQ/taskvisor/blob/main/examples/custom_subscriber.rs
//! [logging]: https://github.com/soltiHQ/taskvisor/blob/main/examples/logging.rs
//! [tracing]: https://github.com/soltiHQ/taskvisor/blob/main/examples/tracing.rs
//! [metrics]: https://github.com/soltiHQ/taskvisor/blob/main/examples/metrics.rs
//! [tenant sync]: https://github.com/soltiHQ/taskvisor/blob/main/examples/tenant_sync.rs
//! [controller slots]: https://github.com/soltiHQ/taskvisor/blob/main/examples/controller_slots.rs
//! [controller admission]: https://github.com/soltiHQ/taskvisor/blob/main/examples/controller_admission.rs
//!
//! ## Choose the runtime entry point
//!
//! | Entry point | Use it when |
//! |-------------------------------------|----------------------------------------------|
//! | [`Supervisor::run`] | A fixed batch finishes naturally |
//! | [`Supervisor::run_until`] | A fixed batch stops on an application future |
//! | [`Supervisor::run_with_os_signals`] | Taskvisor should install signal handlers |
//! | [`Supervisor::serve`] | Work is added and managed at runtime |
//!
//! `run` and `run_until` do not install operating-system signal handlers.
//! `run_with_os_signals` is the explicit process-wide opt-in. Dynamic mode
//! returns a [`SupervisorHandle`] with add, query, cancel, remove, and shutdown methods.
//!
//! [`Supervisor::new`] accepts runtime configuration and subscribers with default task settings.
//! Use [`Supervisor::builder`] when you need custom [`TaskDefaults`], controller admission,
//! or typed construction errors through [`SupervisorBuilder::try_build`].
//!
//! ## Choose task behavior
//!
//! | Constructor | After success | After a retry-eligible failure |
//! |---------------------------|--------------------------------|--------------------------------|
//! | [`TaskSpec::once`] | Stop | Stop |
//! | [`TaskSpec::restartable`] | Stop | Retry if the limit allows |
//! | [`TaskSpec::periodic`] | Wait its interval, then repeat | Retry if the limit allows |
//!
//! Each registration has one [`TaskId`] and one internal actor. Attempts for that ID never overlap.
//! [`RestartPolicy`] decides whether success repeats and whether a retryable failure may run again.
//! The retry limit restricts only repeats after failure. [`BackoffPolicy`] and [`JitterPolicy`]
//! control failure delays. A timeout applies to one attempt. The default retry limit is unlimited;
//! set [`TaskSpec::with_max_retries`] or a [`TaskDefaults`] limit when repeated failure must eventually stop the task.
//!
//! [`Task::spawn`] should return its future promptly. Put the task's work inside that future, and move
//! blocking or CPU-heavy work off Tokio worker threads. Long-running work must observe [`TaskContext::cancelled`]
//! or use [`TaskContext::run_until_cancelled`]. Return [`TaskError::Canceled`] after a cooperative stop.
//! Return [`TaskError::Fail`] for a retry-eligible failure or [`TaskError::Fatal`] when the actor must stop.
//!
//! ## Get results or observe events
//!
//! [`SupervisorHandle::add_and_watch`] returns a [`TaskWaiter`] for a direct final [`TaskOutcome`].
//! A watched result does not depend on the lossy event path, but it is still in-memory and is not
//! durable across process termination.
//!
//! [`Event`] and [`Subscribe`] are for logs, metrics, tracing, and live diagnostics. The shared event bus
//! and each subscriber queue are bounded. Event delivery is best-effort and must not drive application correctness.
//!
//! ## Cancellation and shutdown boundary
//!
//! Cancellation starts cooperatively. At the configured grace deadline, Taskvisor may report [`TaskOutcome::ForceAborted`]
//! while it keeps owning the unfinished actor until physical exit. While that actor remains active, its synchronous
//! task code or attempt-future destructor may keep its task name and capacity reservation owned.
//! Later isolated destruction of terminal task values keeps capacity reserved but does not keep the task name reserved.
//!
//! Dropping a non-final public owner leaves the runtime running. Dropping the final owner can request cancellation but
//! cannot wait for cleanup. Call [`SupervisorHandle::shutdown`] when the cleanup result matters.
//!
//! ## Architecture at a glance
//!
//! ```text
//! application
//! ├── static batch ──► Supervisor::run*
//! ├── dynamic task ──► SupervisorHandle::add*
//! └── keyed task ──► SupervisorHandle::submit* ──► controller
//!
//! registry ──► TaskActor ──► sequential attempts
//!
//! runtime components ──► bounded event bus ──► subscriber queues
//!
//! registry cleanup or watched rejection ──► TaskWaiter
//! ```
//!
//! The registry is the source of truth for registered task membership. The controller owns
//! submissions that have not reached the registry. Events only observe the lifecycle.
//! Watched outcomes use a separate one-shot path.
//!
//! ## Crate layout
//!
//! - [`tasks`] defines work, cancellation context, and task specifications.
//! - [`policies`] defines restart and retry timing.
//! - [`core`] exposes construction, runtime control, outcomes, and configuration.
//! - [`events`] and [`subscribers`] define best-effort observability.
//! - [`error`] maps the public error types to their API boundaries.
//! - [`identity`] explains task IDs, names, and controller slots.
//! - [`prelude`] re-exports the common application-facing types.
//!
//! Contributors can follow the [source guide](https://github.com/soltiHQ/taskvisor/blob/main/src/ARCHITECTURE.md)
//! for runtime ownership, data flow, and test entry points.
//!
//! ## Feature flags
//!
//! - `controller` enables keyed admission and is enabled by default.
//! - `logging` enables the built-in standard-output subscriber.
//! - `tracing` enables the built-in `tracing` bridge.
//! - `tokio-util-interop` exposes Tokio's cancellation token type.
//! - `test-util` exposes constructors intended for external tests.
/// Compiles runnable Rust code blocks in `README.md` as doctests.
;
/// Compiles runnable Rust code blocks in `guide.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 ;