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 new(
45        child: A::Nonce,
46        outcome: Result<Exit<A>, Crash>,
47        reason: SupervisionFailureReason,
48    ) -> Self {
49        Self {
50            child,
51            outcome,
52            reason,
53        }
54    }
55
56    #[must_use]
57    pub const fn into_exit(self) -> Exit<A> {
58        Exit::SupervisionFailed(self.reason)
59    }
60}
61
62/// Pure policy applied when a supervisor cannot preserve its child topology.
63pub type SupervisionFailureReaction<B> =
64    fn(
65        &mut B,
66        &SupervisionFailure<<B as Behavior>::Addr>,
67    ) -> Result<Become<<B as Behavior>::Addr>, <B as Behavior>::Error>;
68
69/// Retire the failed slot and keep the supervisor alive.
70///
71/// # Errors
72/// This supplied policy never returns a controlled behavior error.
73pub fn retire_on_supervision_failure<B: Behavior>(
74    _behavior: &mut B,
75    _failure: &SupervisionFailure<B::Addr>,
76) -> Result<Become<B::Addr>, B::Error> {
77    Ok(Step::Continue)
78}
79
80/// Stop the supervisor with a typed failure outcome.
81///
82/// # Errors
83/// This supplied policy never returns a controlled behavior error.
84pub fn stop_on_supervision_failure<B: Behavior>(
85    _behavior: &mut B,
86    failure: &SupervisionFailure<B::Addr>,
87) -> Result<Become<B::Addr>, B::Error> {
88    Ok(Step::Stop(failure.into_exit()))
89}