rustrade_integration/socket/
backoff.rs1pub trait ReconnectBackoff {
3 fn reconnect_backoff(&mut self, reconnection_attempt: u32) -> std::time::Duration;
5}
6
7impl<F> ReconnectBackoff for F
8where
9 F: FnMut(u32) -> std::time::Duration,
10{
11 #[inline]
12 fn reconnect_backoff(&mut self, reconnection_attempt: u32) -> std::time::Duration {
13 self(reconnection_attempt)
14 }
15}
16
17#[derive(Debug, Copy, Clone, PartialEq)]
21pub struct DefaultBackoff;
22
23impl ReconnectBackoff for DefaultBackoff {
24 fn reconnect_backoff(&mut self, reconnection_attempt: u32) -> std::time::Duration {
25 match reconnection_attempt {
26 0 => std::time::Duration::ZERO,
27 n => std::time::Duration::from_millis(2u64.pow(n.min(15)) + 10),
28 }
29 }
30}
31
32#[cfg(test)]
33#[allow(clippy::unwrap_used)] mod tests {
35 use super::*;
36 use std::time::Duration;
37
38 #[test]
39 fn test_default_backoff_zero() {
40 let mut backoff = DefaultBackoff;
41 assert_eq!(backoff.reconnect_backoff(0), Duration::ZERO);
42 }
43
44 #[test]
45 fn test_default_backoff_first_attempt() {
46 let mut backoff = DefaultBackoff;
47 assert_eq!(backoff.reconnect_backoff(1), Duration::from_millis(12));
48 }
49
50 #[test]
51 fn test_default_backoff_at_cap() {
52 let mut backoff = DefaultBackoff;
53 assert_eq!(backoff.reconnect_backoff(15), Duration::from_millis(32778));
55 }
56
57 #[test]
58 fn test_default_backoff_beyond_cap() {
59 let mut backoff = DefaultBackoff;
60 assert_eq!(backoff.reconnect_backoff(16), Duration::from_millis(32778));
62 }
63
64 #[test]
65 fn test_default_backoff_u32_max() {
66 let mut backoff = DefaultBackoff;
67 assert_eq!(
68 backoff.reconnect_backoff(u32::MAX),
69 Duration::from_millis(32778)
70 );
71 }
72
73 #[test]
74 fn test_closure_backoff() {
75 let mut backoff = |n: u32| Duration::from_secs(n as u64);
76 assert_eq!(backoff.reconnect_backoff(5), Duration::from_secs(5));
77 }
78}