use std::time::Duration;
pub struct ReconnectionStrategy {
current_delay: Duration,
initial_delay: Duration,
max_delay: Duration,
}
impl ReconnectionStrategy {
pub fn new() -> Self {
Self {
current_delay: Duration::from_secs(0),
initial_delay: Duration::from_secs(2),
max_delay: Duration::from_secs(120), }
}
pub fn next_delay(&mut self) -> Duration {
if self.current_delay.is_zero() {
self.current_delay = self.initial_delay;
} else {
self.current_delay *= 2;
if self.current_delay > self.max_delay {
self.current_delay = self.max_delay;
}
}
self.current_delay
}
pub fn reset(&mut self) {
self.current_delay = Duration::from_secs(0);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_exponential_backoff() {
let mut strategy = ReconnectionStrategy::new();
assert_eq!(strategy.next_delay(), Duration::from_secs(2));
assert_eq!(strategy.next_delay(), Duration::from_secs(4));
assert_eq!(strategy.next_delay(), Duration::from_secs(8));
assert_eq!(strategy.next_delay(), Duration::from_secs(16));
assert_eq!(strategy.next_delay(), Duration::from_secs(32));
assert_eq!(strategy.next_delay(), Duration::from_secs(64));
assert_eq!(strategy.next_delay(), Duration::from_secs(120)); assert_eq!(strategy.next_delay(), Duration::from_secs(120));
strategy.reset();
assert_eq!(strategy.next_delay(), Duration::from_secs(2));
}
}