1use std::time::Duration;
2
3#[derive(Debug, Clone)]
8pub struct ReconnectPolicy {
9 base_delay: Duration,
10 max_delay: Duration,
11 max_retries: Option<u32>,
12 current_attempt: u32,
13}
14
15impl ReconnectPolicy {
16 pub fn new(base_delay: Duration, max_delay: Duration, max_retries: Option<u32>) -> Self {
22 Self {
23 base_delay,
24 max_delay,
25 max_retries,
26 current_attempt: 0,
27 }
28 }
29
30 pub fn default_policy() -> Self {
32 Self::new(Duration::from_secs(1), Duration::from_secs(30), None)
33 }
34
35 pub fn next_delay(&mut self) -> Option<Duration> {
39 if let Some(max) = self.max_retries
40 && self.current_attempt >= max
41 {
42 return None;
43 }
44
45 let multiplier = 1u32.checked_shl(self.current_attempt).unwrap_or(u32::MAX);
46 let delay = self.base_delay.saturating_mul(multiplier);
47 let delay = delay.min(self.max_delay);
48
49 self.current_attempt += 1;
50
51 Some(delay)
52 }
53
54 pub fn reset(&mut self) {
56 self.current_attempt = 0;
57 }
58
59 pub fn attempts(&self) -> u32 {
61 self.current_attempt
62 }
63}
64
65#[cfg(test)]
66mod tests;