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
//! # Worker: Long-Running Task with Graceful Shutdown
//!
//! A background worker that ticks every 500ms and exits cleanly on Ctrl+C.
//! This is the canonical pattern for any task that runs indefinitely.
//!
//! ## What this shows
//!
//! - **Cooperative cancellation** via `tokio::select!` + `ctx.cancelled()`.
//! Every long-running task **MUST** observe its `CancellationToken`.
//! Without it, the task would keep running inside `sleep()` and ignore the shutdown signal until the grace period expires.
//! - `TaskSpec::restartable(task)` uses `RestartPolicy::OnFailure` by default:
//! the worker restarts only if it returns `Err`, not on `Ok`.
//!
//! ## Why `ctx.cancelled()` matters
//!
//! Tokio **does NOT kill futures**: it cancels them cooperatively.
//! When the supervisor shuts down, it cancels the task's `CancellationToken`.
//! If your task is awaiting `sleep(10s)`, it won't notice until the sleep finishes.
//! `tokio::select!` with `ctx.cancelled()` lets the task react immediately.
//!
//! Two equivalent patterns:
//! ```text
//! // Pattern 1: select! (recommended for loops / long waits)
//! tokio::select! {
//! _ = ctx.cancelled() => return Ok(()),
//! _ = do_work() => { ... }
//! }
//!
//! // Pattern 2: check (ok for short, non-blocking tasks)
//! if ctx.is_cancelled() { return Ok(()); }
//! do_quick_work().await;
//! ```
//!
//! ## Runtime flavor
//!
//! We use `current_thread` here because a single-threaded runtime is enough for examples and tests.
//!
//! *It can be used with `#[tokio::main]` (defaults to multi-thread): taskvisor works with both.*
//!
//! ## Run
//!
//! ```bash
//! cargo run --example worker
//! # Press Ctrl+C to stop
//! ```
//!
//! ## Next
//!
//! | Example | What it adds |
//! |------------------------------|---------------------------------------|
//! | [`periodic.rs`](periodic.rs) | Task that repeats on a schedule |
//! | [`multiple`](multiple) | Several tasks with different policies |
//!
use Duration;
use *;
async