tiny_tokio_actor/actor/
supervision.rs

1use std::{
2    sync::{Arc, Mutex},
3    time::Duration,
4};
5
6use backoff::backoff::Backoff as InnerBackoff;
7
8/// A SupervisionStrategy defined what to do when an actor fails at startup.
9/// Currently there are two choices: Stop the actor and do nothing, or Retry
10/// the startup. For Retry you can set a RetryStrategy.
11#[derive(Debug)]
12pub enum SupervisionStrategy {
13    Stop,
14    Retry(Box<dyn RetryStrategy>),
15}
16
17/// Trait to define a RetryStrategy. You can use this trait to define your
18/// custom retry strategy.
19pub trait RetryStrategy: std::fmt::Debug + Send + Sync {
20    /// Maximum number of tries before permanently failing an actor
21    fn max_retries(&self) -> usize;
22    /// Wait duration before retrying
23    fn next_backoff(&mut self) -> Option<Duration>;
24}
25
26/// A Retry strategy that immediately retries an actor that failed to start
27#[derive(Debug, Default)]
28pub struct NoIntervalStrategy {
29    max_retries: usize,
30}
31
32impl NoIntervalStrategy {
33    pub fn new(max_retries: usize) -> Self {
34        NoIntervalStrategy { max_retries }
35    }
36}
37
38impl RetryStrategy for NoIntervalStrategy {
39    fn max_retries(&self) -> usize {
40        self.max_retries
41    }
42
43    fn next_backoff(&mut self) -> Option<Duration> {
44        None
45    }
46}
47
48/// A retry strategy that retries an actor with a fixed wait period before
49/// retrying.
50#[derive(Debug, Default)]
51pub struct FixedIntervalStrategy {
52    max_retries: usize,
53    duration: Duration,
54}
55
56impl FixedIntervalStrategy {
57    pub fn new(max_retries: usize, duration: Duration) -> Self {
58        FixedIntervalStrategy {
59            max_retries,
60            duration,
61        }
62    }
63}
64
65impl RetryStrategy for FixedIntervalStrategy {
66    fn max_retries(&self) -> usize {
67        self.max_retries
68    }
69
70    fn next_backoff(&mut self) -> Option<Duration> {
71        Some(self.duration)
72    }
73}
74
75/// A retry strategy that retries an actor with an exponential backoff wait
76/// period before retrying.
77#[derive(Debug, Default)]
78pub struct ExponentialBackoffStrategy {
79    max_retries: usize,
80    inner: Arc<Mutex<backoff::ExponentialBackoff>>,
81}
82
83impl ExponentialBackoffStrategy {
84    pub fn new(max_retries: usize) -> Self {
85        ExponentialBackoffStrategy {
86            max_retries,
87            inner: Arc::new(Mutex::new(backoff::ExponentialBackoff::default())),
88        }
89    }
90}
91
92impl RetryStrategy for ExponentialBackoffStrategy {
93    fn max_retries(&self) -> usize {
94        self.max_retries
95    }
96
97    fn next_backoff(&mut self) -> Option<Duration> {
98        self.inner.lock().ok().and_then(|mut eb| eb.next_backoff())
99    }
100}