use std::time::Duration;
#[derive(Debug, Clone)]
pub struct RetryPolicy {
pub max_attempts: u8,
pub initial_backoff: Duration,
pub max_backoff: Duration,
pub backoff_multiplier: u8,
}
impl Default for RetryPolicy {
fn default() -> Self {
Self {
max_attempts: 5,
initial_backoff: Duration::from_millis(50),
max_backoff: Duration::from_secs(5),
backoff_multiplier: 5,
}
}
}
impl RetryPolicy {
pub fn backoff(&self, current_wait: Duration) -> Duration {
if current_wait == Duration::ZERO {
return self.initial_backoff;
}
(current_wait * u32::from(self.backoff_multiplier)).min(self.max_backoff)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_backoff() {
let policy = RetryPolicy::default();
let mut current_wait = Duration::ZERO;
current_wait = policy.backoff(current_wait);
assert_eq!(current_wait, policy.initial_backoff);
current_wait = policy.backoff(current_wait);
assert_eq!(current_wait, Duration::from_millis(250));
current_wait = policy.backoff(current_wait);
assert_eq!(current_wait, Duration::from_millis(1250));
current_wait = policy.backoff(current_wait);
assert_eq!(current_wait, policy.max_backoff);
current_wait = policy.backoff(Duration::ZERO);
assert_eq!(current_wait, policy.initial_backoff);
}
}