orleans_rust_client/
retry.rs1use std::time::Duration;
10
11#[derive(Debug, Clone)]
13pub struct RetryPolicy {
14 pub max_retries: u32,
17 pub initial_backoff: Duration,
19 pub max_backoff: Duration,
21 pub backoff_multiplier: f64,
23}
24
25impl RetryPolicy {
26 #[must_use]
28 pub fn disabled() -> Self {
29 Self {
30 max_retries: 0,
31 initial_backoff: Duration::ZERO,
32 max_backoff: Duration::ZERO,
33 backoff_multiplier: 1.0,
34 }
35 }
36
37 #[must_use]
40 pub fn conservative() -> Self {
41 Self {
42 max_retries: 2,
43 initial_backoff: Duration::from_millis(100),
44 max_backoff: Duration::from_secs(2),
45 backoff_multiplier: 2.0,
46 }
47 }
48
49 #[must_use]
51 pub fn is_enabled(&self) -> bool {
52 self.max_retries > 0
53 }
54
55 #[must_use]
57 pub fn backoff_for(&self, attempt: u32) -> Duration {
58 if attempt == 0 {
59 return Duration::ZERO;
60 }
61 let exp = self.backoff_multiplier.powi((attempt - 1) as i32);
62 let millis = self.initial_backoff.as_secs_f64() * 1000.0 * exp;
63 let capped = millis.min(self.max_backoff.as_secs_f64() * 1000.0);
64 Duration::from_millis(capped as u64)
65 }
66}
67
68impl Default for RetryPolicy {
69 fn default() -> Self {
70 Self::disabled()
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn default_is_disabled() {
80 assert!(!RetryPolicy::default().is_enabled());
81 assert_eq!(RetryPolicy::default().backoff_for(1), Duration::ZERO);
82 assert_eq!(RetryPolicy::conservative().backoff_for(0), Duration::ZERO);
84 }
85
86 #[test]
87 fn conservative_is_bounded() {
88 let policy = RetryPolicy::conservative();
89 assert!(policy.is_enabled());
90 assert_eq!(policy.max_retries, 2);
91 }
92
93 #[test]
94 fn backoff_grows_then_caps() {
95 let policy = RetryPolicy {
96 max_retries: 10,
97 initial_backoff: Duration::from_millis(100),
98 max_backoff: Duration::from_millis(500),
99 backoff_multiplier: 2.0,
100 };
101 assert_eq!(policy.backoff_for(1), Duration::from_millis(100));
102 assert_eq!(policy.backoff_for(2), Duration::from_millis(200));
103 assert_eq!(policy.backoff_for(3), Duration::from_millis(400));
104 assert_eq!(policy.backoff_for(4), Duration::from_millis(500));
106 }
107}