use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Backoff {
pub initial_ms: u64,
pub max_ms: u64,
next_ms: u64,
}
impl Default for Backoff {
fn default() -> Self {
Self::new(1_000, 30_000)
}
}
impl Backoff {
pub fn new(initial_ms: u64, max_ms: u64) -> Self {
Self { initial_ms, max_ms, next_ms: initial_ms }
}
pub fn next_delay(&mut self) -> u64 {
let delay = self.next_ms;
self.next_ms = (self.next_ms.saturating_mul(2)).min(self.max_ms);
delay
}
pub fn reset(&mut self) {
self.next_ms = self.initial_ms;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn doubles_to_the_cap_and_resets() {
let mut b = Backoff::default();
let delays: Vec<u64> = (0..7).map(|_| b.next_delay()).collect();
assert_eq!(delays, [1_000, 2_000, 4_000, 8_000, 16_000, 30_000, 30_000]);
b.reset();
assert_eq!(b.next_delay(), 1_000);
}
}