bililive_core/retry/
policy.rs1use std::time::Duration;
2
3use rand::distributions::Uniform;
4use rand::{thread_rng, Rng};
5
6#[derive(Debug, Clone)]
8pub struct BEBIterator {
9 unit: Duration,
10 truncate: u32,
11 fail: u32,
12 count: u32,
13}
14
15impl Default for BEBIterator {
16 fn default() -> Self {
17 Self::new(Duration::from_secs(1), 5, 10)
18 }
19}
20
21impl BEBIterator {
22 #[must_use]
36 pub fn new(unit: Duration, truncate: u32, fail: u32) -> Self {
37 assert!(truncate < fail, "truncate >= fail");
38 Self {
39 unit,
40 truncate,
41 fail,
42 count: 0,
43 }
44 }
45}
46
47impl Iterator for BEBIterator {
48 type Item = Duration;
49
50 fn next(&mut self) -> Option<Self::Item> {
51 if self.count >= self.fail {
52 None
53 } else {
54 let max_delay = 2_u32.pow(if self.count >= self.truncate {
55 self.truncate
56 } else {
57 self.count
58 });
59 let between = Uniform::new_inclusive(0, max_delay * 100);
60 let units = thread_rng().sample(between);
61 Some(self.unit * units / 100)
62 }
63 }
64}