use rand::RngExt;
use std::time::Duration;
#[derive(Debug, Clone, Copy)]
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: 4,
base_delay: Duration::from_millis(500),
max_delay: Duration::from_secs(8),
}
}
}
impl RetryPolicy {
pub fn delay_for(&self, n: u32) -> Duration {
let shift = n.saturating_sub(1).min(10);
let ceiling = self
.base_delay
.saturating_mul(1u32 << shift)
.min(self.max_delay);
let millis = rand::rng().random_range(0..=ceiling.as_millis() as u64);
Duration::from_millis(millis)
}
}
pub fn should_retry_status(status: u16) -> bool {
matches!(status, 429 | 500 | 502 | 503 | 504)
}