use std::time::Duration;
pub(crate) struct PollBackoff {
base: Duration,
max: Duration,
current: Duration,
}
impl PollBackoff {
pub(crate) fn new(base: Duration, max: Option<Duration>) -> Self {
let max = max.unwrap_or(base).max(base);
Self {
base,
max,
current: base,
}
}
pub(crate) fn idle_delay(&mut self) -> Duration {
let delay = self.current;
self.current = (self.current * 2).min(self.max);
delay
}
pub(crate) fn reset(&mut self) {
self.current = self.base;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn poll_backoff_disabled_when_no_max() {
let base = Duration::from_millis(100);
let mut b = PollBackoff::new(base, None);
assert_eq!(b.idle_delay(), base);
assert_eq!(b.idle_delay(), base); }
#[test]
fn poll_backoff_doubles_up_to_max_and_resets() {
let base = Duration::from_millis(100);
let mut b = PollBackoff::new(base, Some(Duration::from_millis(500)));
assert_eq!(b.idle_delay(), Duration::from_millis(100));
assert_eq!(b.idle_delay(), Duration::from_millis(200));
assert_eq!(b.idle_delay(), Duration::from_millis(400));
assert_eq!(b.idle_delay(), Duration::from_millis(500)); assert_eq!(b.idle_delay(), Duration::from_millis(500));
b.reset();
assert_eq!(b.idle_delay(), Duration::from_millis(100)); }
}