coerce/persistent/
failure.rs1use crate::actor::context::ActorContext;
2
3use std::fmt;
4use std::fmt::{Display, Formatter};
5use std::time::Duration;
6
7#[derive(Copy, Clone)]
8pub enum RecoveryFailurePolicy {
9 Retry(Retry),
10 StopActor,
11 Panic,
12}
13
14#[derive(Copy, Clone)]
15pub enum PersistFailurePolicy {
16 Retry(Retry),
17 ReturnErr,
18 StopActor,
19 Panic,
20}
21
22#[derive(Copy, Clone)]
23pub enum Retry {
24 UntilSuccess {
25 delay: Option<Duration>,
26 },
27 MaxAttempts {
28 max_attempts: usize,
29 delay: Option<Duration>,
30 },
31}
32
33pub(crate) async fn should_retry(ctx: &mut ActorContext, attempts: &usize, retry: Retry) -> bool {
34 match retry {
35 Retry::UntilSuccess { delay } => {
36 if let Some(delay) = delay {
37 tokio::time::sleep(delay).await;
38 }
39 }
40
41 Retry::MaxAttempts {
42 max_attempts,
43 delay,
44 } => {
45 if attempts >= &max_attempts {
46 ctx.stop(None);
47 return false;
48 }
49
50 if let Some(delay) = delay {
51 tokio::time::sleep(delay).await;
52 }
53 }
54 }
55 return true;
56}
57
58impl Display for RecoveryFailurePolicy {
59 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
60 match &self {
61 RecoveryFailurePolicy::StopActor => write!(f, "StopActor"),
62 RecoveryFailurePolicy::Retry(r) => write!(f, "Retry({})", r),
63 RecoveryFailurePolicy::Panic => write!(f, "Panic"),
64 }
65 }
66}
67
68impl Display for PersistFailurePolicy {
69 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
70 match &self {
71 PersistFailurePolicy::StopActor => write!(f, "StopActor"),
72 PersistFailurePolicy::Retry(r) => write!(f, "Retry({})", r),
73 PersistFailurePolicy::Panic => write!(f, "Panic"),
74 PersistFailurePolicy::ReturnErr => write!(f, "ReturnErr"),
75 }
76 }
77}
78
79impl Display for Retry {
80 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
81 match &self {
82 Retry::UntilSuccess { delay } => {
83 if let Some(delay) = delay.as_ref() {
84 write!(f, "UntilSuccess(delay={} millis)", delay.as_millis())
85 } else {
86 write!(f, "UntilSuccess(delay=None)")
87 }
88 }
89
90 Retry::MaxAttempts {
91 max_attempts,
92 delay,
93 } => {
94 if let Some(delay) = delay.as_ref() {
95 write!(
96 f,
97 "MaxAttempts(max_attempts={}, delay={} millis)",
98 max_attempts,
99 delay.as_millis()
100 )
101 } else {
102 write!(f, "MaxAttempts(max_attempts={}, delay=None)", max_attempts)
103 }
104 }
105 }
106 }
107}
108
109impl Default for RecoveryFailurePolicy {
110 fn default() -> Self {
111 RecoveryFailurePolicy::Retry(Retry::UntilSuccess {
112 delay: Some(Duration::from_millis(500)),
113 })
114 }
115}
116
117impl Default for PersistFailurePolicy {
118 fn default() -> Self {
119 PersistFailurePolicy::Retry(Retry::UntilSuccess {
120 delay: Some(Duration::from_millis(500)),
121 })
122 }
123}