Skip to main content

behavior/supervision/
policy.rs

1//! Concrete supervision strategies, restart policy, and failure reactions.
2
3use crate::{Address, Become, Behavior, Crash, Exit, Step, SupervisionFailureReason};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum Strategy {
7    OneForOne,
8    OneForAll,
9    RestForOne,
10}
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum RestartPolicy {
14    Permanent,
15    Transient,
16    Temporary,
17}
18
19#[must_use]
20pub const fn restart_one() -> Strategy {
21    Strategy::OneForOne
22}
23
24#[must_use]
25pub const fn restart_all() -> Strategy {
26    Strategy::OneForAll
27}
28
29#[must_use]
30pub const fn restart_rest() -> Strategy {
31    Strategy::RestForOne
32}
33
34/// A typed failure of the supervisor's child-topology contract.
35#[derive(Debug, Clone, Copy, PartialEq, Eq)]
36pub struct SupervisionFailure<A: Address> {
37    pub child: A::Nonce,
38    pub outcome: Result<Exit<A>, Crash>,
39    pub reason: SupervisionFailureReason,
40}
41
42impl<A: Address> SupervisionFailure<A> {
43    #[must_use]
44    pub const fn into_exit(self) -> Exit<A> {
45        Exit::SupervisionFailed(self.reason)
46    }
47}
48
49/// Pure policy applied when a supervisor cannot preserve its child topology.
50pub type SupervisionFailureReaction<B> =
51    fn(
52        &mut B,
53        &SupervisionFailure<<B as Behavior>::Addr>,
54    ) -> Result<Become<<B as Behavior>::Addr>, <B as Behavior>::Error>;
55
56/// Retire the failed slot and keep the supervisor alive.
57///
58/// # Errors
59/// This supplied policy never returns a controlled behavior error.
60pub fn retire_on_supervision_failure<B: Behavior>(
61    _behavior: &mut B,
62    _failure: &SupervisionFailure<B::Addr>,
63) -> Result<Become<B::Addr>, B::Error> {
64    Ok(Step::Continue)
65}
66
67/// Stop the supervisor with a typed failure outcome.
68///
69/// # Errors
70/// This supplied policy never returns a controlled behavior error.
71pub fn stop_on_supervision_failure<B: Behavior>(
72    _behavior: &mut B,
73    failure: &SupervisionFailure<B::Addr>,
74) -> Result<Become<B::Addr>, B::Error> {
75    Ok(Step::Stop(failure.into_exit()))
76}