relay_server/utils/
retry.rs1use std::time::Duration;
2
3use backon::BackoffBuilder;
4use backon::ExponentialBackoff;
5use backon::ExponentialBuilder;
6
7const DEFAULT_MULTIPLIER: f32 = 1.5;
9const INITIAL_INTERVAL: Duration = Duration::from_millis(1000);
11
12#[derive(Debug)]
14pub struct RetryBackoff {
15 builder: ExponentialBuilder,
16 backoff: ExponentialBackoff,
17 attempt: usize,
18}
19
20impl RetryBackoff {
21 pub fn new(max_interval: Duration) -> Self {
23 let builder = ExponentialBuilder::new()
24 .with_factor(DEFAULT_MULTIPLIER)
25 .with_min_delay(INITIAL_INTERVAL)
26 .with_max_delay(max_interval)
27 .without_max_times();
28
29 RetryBackoff {
30 backoff: builder.build(),
31 builder,
32 attempt: 0,
33 }
34 }
35
36 pub fn reset(&mut self) {
38 self.backoff = self.builder.build();
39 self.attempt = 0;
40 }
41
42 pub fn started(&self) -> bool {
44 self.attempt > 0
45 }
46
47 pub fn attempt(&self) -> usize {
49 self.attempt
50 }
51
52 pub fn next_backoff(&mut self) -> Duration {
54 let duration = match self.attempt {
55 0 => Duration::ZERO,
56 _ => self.backoff.next().unwrap(),
57 };
58
59 self.attempt += 1;
60 duration
61 }
62}