rig_core/http_client/
retry.rs1use super::Error;
4use std::time::Duration;
5
6pub trait RetryPolicy {
7 fn retry(&self, error: &Error, last_retry: Option<(usize, Duration)>) -> Option<Duration>;
10
11 fn set_reconnection_time(&mut self, duration: Duration);
13}
14
15#[derive(Debug, Clone)]
17pub struct ExponentialBackoff {
18 pub start: Duration,
20 pub factor: f64,
22 pub max_duration: Option<Duration>,
24 pub max_retries: Option<usize>,
26}
27
28impl ExponentialBackoff {
29 pub const fn new(
31 start: Duration,
32 factor: f64,
33 max_duration: Option<Duration>,
34 max_retries: Option<usize>,
35 ) -> Self {
36 Self {
37 start,
38 factor,
39 max_duration,
40 max_retries,
41 }
42 }
43}
44
45impl RetryPolicy for ExponentialBackoff {
46 fn retry(&self, _error: &Error, last_retry: Option<(usize, Duration)>) -> Option<Duration> {
47 if let Some((retry_num, last_duration)) = last_retry {
48 if self
49 .max_retries
50 .is_none_or(|max_retries| retry_num < max_retries)
51 {
52 let duration = last_duration.mul_f64(self.factor);
53 if let Some(max_duration) = self.max_duration {
54 Some(duration.min(max_duration))
55 } else {
56 Some(duration)
57 }
58 } else {
59 None
60 }
61 } else {
62 Some(self.start)
63 }
64 }
65 fn set_reconnection_time(&mut self, duration: Duration) {
66 self.start = duration;
67 if let Some(max_duration) = self.max_duration {
68 self.max_duration = Some(max_duration.max(duration))
69 }
70 }
71}
72
73pub const DEFAULT_RETRY: ExponentialBackoff = ExponentialBackoff::new(
75 Duration::from_millis(300),
76 2.,
77 Some(Duration::from_secs(5)),
78 None,
79);