use std::time::Duration;
use crate::contracts::RunnerRetryConfig;
#[derive(Debug, Clone, Copy)]
pub(crate) struct RunnerRetryPolicy {
pub max_attempts: u32,
pub base_backoff: Duration,
pub multiplier: f64,
pub max_backoff: Duration,
pub jitter_ratio: f64,
}
impl RunnerRetryPolicy {
pub(crate) fn from_config(cfg: &RunnerRetryConfig) -> anyhow::Result<Self> {
let max_attempts = cfg.max_attempts.unwrap_or(3).max(1);
let base_backoff = Duration::from_millis(cfg.base_backoff_ms.unwrap_or(1000) as u64);
let multiplier = cfg.multiplier.unwrap_or(2.0).max(1.0);
let max_backoff = Duration::from_millis(cfg.max_backoff_ms.unwrap_or(30_000) as u64);
let jitter_ratio = cfg.jitter_ratio.unwrap_or(0.2).clamp(0.0, 1.0);
Ok(Self {
max_attempts,
base_backoff,
multiplier,
max_backoff,
jitter_ratio,
})
}
#[allow(dead_code)]
pub(crate) fn enabled(self) -> bool {
self.max_attempts > 1
}
}
impl Default for RunnerRetryPolicy {
fn default() -> Self {
Self {
max_attempts: 3,
base_backoff: Duration::from_millis(1000),
multiplier: 2.0,
max_backoff: Duration::from_millis(30_000),
jitter_ratio: 0.2,
}
}
}