use std::time::Duration;
#[derive(Clone, Debug)]
pub struct RetryPolicy {
pub max_attempts: u32,
pub base_delay: Duration,
pub max_delay: Duration,
pub jitter: bool,
}
impl Default for RetryPolicy {
fn default() -> Self {
Self {
max_attempts: 3,
base_delay: Duration::from_millis(200),
max_delay: Duration::from_secs(5),
jitter: true,
}
}
}
impl RetryPolicy {
#[must_use]
pub fn delay_for(&self, attempt: u32) -> Duration {
let exp = self.base_delay.saturating_mul(2u32.saturating_pow(attempt));
let mut delay = exp.min(self.max_delay);
if self.jitter {
let nanos = delay.as_nanos().min(u128::from(u64::MAX)) as u64;
let jitter = rand::random::<u64>() % (nanos / 2 + 1);
delay = Duration::from_nanos(nanos.saturating_sub(jitter) / 2 + jitter / 2);
}
delay
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum FailurePolicy {
#[default]
KeepLastGood,
FailFast,
FallbackLocal,
}
#[derive(Clone, Debug)]
pub struct RefreshConfig {
pub interval: Duration,
pub retry: RetryPolicy,
pub on_failure: FailurePolicy,
}
impl Default for RefreshConfig {
fn default() -> Self {
Self {
interval: Duration::from_secs(300),
retry: RetryPolicy::default(),
on_failure: FailurePolicy::KeepLastGood,
}
}
}