Skip to main content

behavior_actors/atomic/dynamic_supervisor/
lifecycle.rs

1//! Durable lifecycle messages owned by one configured actor.
2
3use behavior::{
4    Address, Behavior, BehaviorAddr, ChildInputReason, EndpointAddress, EstablishedActor,
5    InterpreterFault, Protocol,
6};
7
8use crate::{
9    ActivationPlan, ChildStopped, InitialWorkerOutcome, ProxyOutcome, ProxyPhase, StableProxy,
10    WorkerAttempt, WorkerCreationRejection, WorkerSubmission,
11};
12
13use crate::atomic::proxy_creation::StableProxyCreationSettlement;
14
15/// Why one keyed service is being removed after its proxy drains.
16#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17pub enum EntryRetirement {
18    /// The accepted worker change was cancelled.
19    Cancellation,
20    /// The initial worker could not become ready.
21    StartFailed,
22    /// Policy selected retirement after the ready worker stopped.
23    UnexpectedWorkerStopped,
24    /// An admitted explicit stop observed the stable proxy's exact exit.
25    Stop,
26    /// Global supervisor shutdown drained or proved absent this entry.
27    Shutdown,
28}
29
30/// Exact reason an admitted keyed-service stop could not complete normally.
31pub enum EntryStopFailureReason {
32    /// The child input capability rejected the shutdown request.
33    ControlRejected(ChildInputReason),
34    /// The interpreter violated its child-input contract.
35    InterpreterCorrupt(InterpreterFault),
36    /// Product traversal ended before attempting the shutdown request.
37    InterpretationSkipped,
38}
39
40/// Typed failure of one admitted explicit keyed-service stop.
41///
42/// The settlement reason and optional exact proxy stop are independent current
43/// values. A missing stop permits restoration; a present stop requires entry
44/// retirement.
45pub struct EntryStopFailure<A>
46where
47    A: Address,
48{
49    pub(super) reason: EntryStopFailureReason,
50    pub(super) stopped: Option<ChildStopped<A>>,
51}
52
53impl<A> EntryStopFailure<A>
54where
55    A: Address,
56{
57    /// Borrow the exact shutdown-settlement reason.
58    #[must_use]
59    pub const fn reason(&self) -> &EntryStopFailureReason {
60        &self.reason
61    }
62
63    /// Borrow the exact proxy stop when it arrived before settlement failed.
64    #[must_use]
65    pub const fn stopped(&self) -> Option<&ChildStopped<A>> {
66        self.stopped.as_ref()
67    }
68
69    /// Transfer the complete independent reason and proxy-stop values.
70    #[must_use]
71    pub fn into_parts(self) -> (EntryStopFailureReason, Option<ChildStopped<A>>) {
72        (self.reason, self.stopped)
73    }
74}
75
76/// Management operation whose cancellation is durably completed.
77#[derive(Clone, Copy, Debug, Eq, PartialEq)]
78pub enum WorkerChange {
79    /// Creation of the entry's first worker.
80    Start,
81    /// Replacement of an existing or unavailable worker.
82    Replacement,
83}
84
85/// Why an accepted worker change cannot publish availability.
86#[derive(Clone, Copy, Debug, Eq, PartialEq)]
87pub enum WorkerChangeInterruption {
88    /// An admitted explicit Stop interrupted an initial start.
89    ExplicitStop {
90        /// Exact stop operation, distinct from the interrupted start operation.
91        operation: u64,
92    },
93    /// Supervisor shutdown interrupted the named worker-change kind.
94    SupervisorShutdown { change: WorkerChange },
95}
96
97/// Complete worker-custody result of one cancelled management operation.
98pub enum CancellationOutcome<Worker, Plan>
99where
100    Worker: Behavior,
101    Plan: ActivationPlan,
102    BehaviorAddr<Worker>: EndpointAddress,
103    StableProxy<Worker, Plan>: Behavior<Protocol = Worker::Protocol>,
104{
105    /// The complete worker submission returned through the cancellation reply.
106    WorkerReturned,
107    /// The emitted proxy input was rejected and moved to diagnostic custody.
108    ProxyInputRejected,
109    /// The proxy produced a late result retained by the lifecycle owner.
110    ProxyReported { outcome: ProxyOutcome<Worker, Plan> },
111}
112
113/// Complete worker disposition when a start is interrupted before availability.
114pub enum InterruptedWorker<Worker, Plan>
115where
116    Worker: Behavior,
117    Plan: ActivationPlan,
118    BehaviorAddr<Worker>: EndpointAddress,
119    StableProxy<Worker, Plan>: Behavior<Protocol = Worker::Protocol>,
120{
121    /// The worker never left the supervisor's local submission.
122    Submission(WorkerSubmission<Worker, Plan>),
123    /// The emitted proxy input was rejected and moved to diagnostic custody.
124    ProxyInputRejected,
125    /// The proxy returned the exact result of the interrupted input.
126    ProxyReported(ProxyOutcome<Worker, Plan>),
127}
128
129/// Exact replacement failure values not retained by the next service state.
130pub enum ReplacementFailure<Worker, Plan>
131where
132    Worker: Behavior,
133    Plan: ActivationPlan,
134    BehaviorAddr<Worker>: EndpointAddress,
135    StableProxy<Worker, Plan>: Behavior<Protocol = Worker::Protocol>,
136{
137    /// StableProxy refused the input without changing its current worker.
138    ProxyRefused {
139        worker: Worker,
140        activation: Plan,
141        phase: ProxyPhase,
142    },
143    /// StableProxy returned the worker after exhausting fresh attempt IDs.
144    WorkerAttemptsExhausted { worker: Worker, activation: Plan },
145    /// Successor creation failed before a worker was committed.
146    WorkerCreationRejected {
147        rejection: WorkerCreationRejection<Worker>,
148        activation: Plan,
149        stopped: Option<ChildStopped<BehaviorAddr<Worker>>>,
150    },
151    /// A committed successor could not become available and was drained.
152    WorkerUnavailable {
153        drain: crate::ProxyDrain<Worker, Plan>,
154    },
155}
156
157/// Durable dynamic-supervisor lifecycle message.
158pub enum DynamicLifecycle<Key, Worker, Plan>
159where
160    Worker: Behavior,
161    Plan: ActivationPlan,
162    BehaviorAddr<Worker>: EndpointAddress,
163    StableProxy<Worker, Plan>: Behavior<Protocol = Worker::Protocol>,
164{
165    Started {
166        key: Key,
167        generation: u64,
168        operation: u64,
169        proxy: EstablishedActor<StableProxy<Worker, Plan>>,
170    },
171    StartCreationRejected {
172        key: Key,
173        generation: u64,
174        submission: WorkerSubmission<Worker, Plan>,
175        creation: StableProxyCreationSettlement<Worker, Plan>,
176    },
177    WorkerChangeInterrupted {
178        key: Key,
179        generation: u64,
180        operation: u64,
181        interruption: WorkerChangeInterruption,
182        worker: InterruptedWorker<Worker, Plan>,
183    },
184    StartInputRejected {
185        key: Key,
186        generation: u64,
187    },
188    ReplacementInputRejected {
189        key: Key,
190        generation: u64,
191        operation: u64,
192    },
193    StartOutcomeRejected {
194        key: Key,
195        generation: u64,
196        operation: u64,
197        outcome: InitialWorkerOutcome<Worker, Plan>,
198    },
199    Replaced {
200        key: Key,
201        generation: u64,
202        operation: u64,
203        proxy: EstablishedActor<StableProxy<Worker, Plan>>,
204    },
205    ReplacementFailed {
206        key: Key,
207        generation: u64,
208        operation: u64,
209        failure: ReplacementFailure<Worker, Plan>,
210    },
211    StopFinished {
212        key: Key,
213        generation: u64,
214        operation: u64,
215        proxy: EstablishedActor<StableProxy<Worker, Plan>>,
216        result: Result<ChildStopped<BehaviorAddr<Worker>>, EntryStopFailure<BehaviorAddr<Worker>>>,
217    },
218    UnexpectedWorkerStopped {
219        key: Key,
220        generation: u64,
221        worker: WorkerAttempt,
222        readiness: Plan::Ready,
223        stopped: ChildStopped<BehaviorAddr<Worker>>,
224        disposition: super::UnexpectedExit,
225    },
226    CommandUnavailable {
227        key: Key,
228        generation: u64,
229        sender: BehaviorAddr<Worker>,
230        proxy_phase: ProxyPhase,
231        command: <Worker::Protocol as Protocol>::Msg,
232    },
233    OperationCancelled {
234        key: Key,
235        generation: u64,
236        operation: u64,
237        change: WorkerChange,
238        outcome: CancellationOutcome<Worker, Plan>,
239    },
240    EntryRetired {
241        key: Key,
242        generation: u64,
243        cause: EntryRetirement,
244    },
245}