1use std::time::Duration;
5
6const FIRST_DELAY: Duration = Duration::from_secs(1);
8const LONGEST_DELAY: Duration = Duration::from_secs(30);
10
11pub(crate) fn retry_count(asked: i64) -> u32 {
14 u32::try_from(asked.max(0)).unwrap_or(u32::MAX)
15}
16
17pub(crate) fn delay(failures: u32) -> Duration {
19 let doublings = failures.saturating_sub(1);
20 FIRST_DELAY
21 .saturating_mul(2_u32.saturating_pow(doublings))
22 .min(LONGEST_DELAY)
23}
24
25#[cfg(test)]
26mod tests {
27 use super::*;
28
29 #[test]
30 fn waits_twice_as_long_after_each_failure_up_to_a_limit() {
31 let waits: Vec<_> = (1..=7).map(|failures| delay(failures).as_secs()).collect();
32 assert_eq!(waits, [1, 2, 4, 8, 16, 30, 30]);
33 assert_eq!(delay(u32::MAX), LONGEST_DELAY);
34 }
35
36 #[test]
37 fn retries_at_least_zero_times() {
38 assert_eq!(retry_count(-1), 0);
39 assert_eq!(retry_count(3), 3);
40 assert_eq!(retry_count(i64::MAX), u32::MAX);
41 }
42}