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
//! # Task identity
//!
//! [`TaskId`] is the opaque identity reserved for one task submission.
//!
//! Direct `add*` methods return it after the registry accepts a task.
//! Controller `submit*` methods return it after queueing, before slot admission.
//! Controller `prepare_submission` exposes it earlier, before the submission can
//! publish any event.
//! The same ID therefore also identifies a controller submission that is rejected without running.
//!
//! ## One identity across the lifecycle
//!
//! Every submission accepted into Taskvisor's command path has one `TaskId`.
//! It is allocated before the first admission decision, then passed unchanged through every stage that the submission reaches:
//!
//! ```text
//! allocate TaskId A
//! │
//! ├── direct add ───────────────────────────────────────────────┐
//! │ │
//! └── optional controller ─► queue[A] ─► slot admission[A] ─────┤
//! │ │
//! └──► rejected[A] (not registered)│
//! ▼
//! registry admission[A]
//! │ │
//! rejected[A] ◄──────────┘ └──► registry[A]
//! (not registered) │
//! ▼
//! task runner[A] ─► attempt 1, 2, ...
//! ▼
//! cleanup[A]
//! ```
//!
//! No new `TaskId` is allocated at admission or between retry attempts.
//! Queue management, registry membership, the managed runner, and completion tracking carry the same `A`.
//! Related lifecycle events expose it so callers can correlate cancellation, logs, and metrics.
//!
//! ## TaskId vs Name vs Slot
//!
//! | Concept | Owned by | Meaning |
//! |------------------|------------|-------------------------------------------------------|
//! | [`TaskId`] | taskvisor | identity of one submission across its full lifecycle |
//! | task name | task | label used for logs, metrics, and registry uniqueness |
//! | controller slot | controller | admission key for "one at a time" scheduling |
//!
//! A task name is unique only while its registry entry exists.
//! After terminal cleanup removes that entry, a later submission may reuse the same name.
//! Reusing a name does not reuse its identity:
//!
//! ```text
//! first submission: name = "worker", slot = "jobs", TaskId = A
//! terminal cleanup: removes A and releases the name "worker"
//! later submission: name = "worker", slot = "jobs", TaskId = B (B != A)
//! ```
//!
//! Each `TaskId` is allocated from a process-local `u64` counter.
//!
//! The counter is not stored across process restarts, and a `TaskId` is not a UUID.
//! If external systems need a persistent identity, store their own ID next to this one.
//!
//! With the `controller` feature, a submitted task also has a slot key (`ControllerSpec::slot_name`).
//! The slot controls admission only; it is not the same thing as the submission identity.
use ;
/// Process-local allocation counter for task identities.
///
/// Starts at `1`.
/// Like all `AtomicU64::fetch_add` counters, it wraps after `2^64` allocations;
/// reaching that limit is outside normal operation.
static TASK_ID_SEQ: AtomicU64 = new;
/// Opaque process-local identity of one task submission.
///
/// Taskvisor allocates it once. With the `controller` feature, this happens before admission so queued work can already be addressed and correlated.
/// A prepared controller submission exposes the allocated value before controller intake and before any event for that value can be published.
/// If admitted, the same value becomes the registry key and remains unchanged through all attempts and terminal cleanup.
///
/// Rejected work keeps its id even though no task body ran.
///
/// Pass the returned value to cancellation and removal operations.
/// The same value correlates the submission's lifecycle [`Event`](crate::Event)s, completion, logs, and metrics within the current process.
///
/// Do not parse its display output.
/// Use [`get`](Self::get) when you need the numeric value.
/// Numeric order is allocation order, not a causal or time order.
;