use std::time::Duration;
use rand::RngExt;
#[derive(Debug, Clone)]
pub struct RetryPolicy {
pub max_attempts: u32,
pub base_delay: Duration,
pub max_delay: Duration,
}
impl Default for RetryPolicy {
fn default() -> Self {
Self {
max_attempts: 3,
base_delay: Duration::from_secs(1),
max_delay: Duration::from_secs(30),
}
}
}
impl RetryPolicy {
#[must_use]
pub fn compute_delay(&self, attempt: u32) -> Duration {
let exp = self
.base_delay
.as_millis()
.saturating_mul(1u128 << attempt.min(20));
let capped = exp.min(self.max_delay.as_millis());
if capped == 0 {
return Duration::ZERO;
}
let jittered = rand::rng().random_range(0..=capped);
Duration::from_millis(u64::try_from(jittered).unwrap_or(u64::MAX))
}
}