#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct FetchPolicy {
pub timeout_ms: u64,
pub retries: u32,
pub retry_factor: u32,
pub retry_min_timeout_ms: u64,
pub retry_max_timeout_ms: u64,
pub warn_timeout_ms: u64,
pub min_speed_kibps: u64,
pub packument_max_bytes: u64,
pub tarball_max_bytes: u64,
}
impl Default for FetchPolicy {
fn default() -> Self {
Self {
timeout_ms: 300_000,
retries: 2,
retry_factor: 10,
retry_min_timeout_ms: 10_000,
retry_max_timeout_ms: 60_000,
warn_timeout_ms: 10_000,
min_speed_kibps: 50,
packument_max_bytes: 200 << 20,
tarball_max_bytes: 1 << 30,
}
}
}
impl FetchPolicy {
pub fn from_ctx(ctx: &aube_settings::ResolveCtx<'_>) -> Self {
Self {
timeout_ms: aube_settings::resolved::fetch_timeout(ctx),
retries: clamp_u32(aube_settings::resolved::fetch_retries(ctx)),
retry_factor: clamp_u32(aube_settings::resolved::fetch_retry_factor(ctx)),
retry_min_timeout_ms: aube_settings::resolved::fetch_retry_mintimeout(ctx),
retry_max_timeout_ms: aube_settings::resolved::fetch_retry_maxtimeout(ctx),
warn_timeout_ms: aube_settings::resolved::fetch_warn_timeout_ms(ctx),
min_speed_kibps: aube_settings::resolved::fetch_min_speed_ki_bps(ctx),
packument_max_bytes: aube_settings::resolved::packument_max_bytes(ctx),
tarball_max_bytes: aube_settings::resolved::tarball_max_bytes(ctx),
}
}
pub fn backoff_for_attempt(&self, attempt: u32) -> std::time::Duration {
let attempt = attempt.max(1);
let factor = u64::from(self.retry_factor.max(1));
let exp = attempt.saturating_sub(1);
let mut wait = self.retry_min_timeout_ms;
for _ in 0..exp {
wait = wait.saturating_mul(factor);
if wait >= self.retry_max_timeout_ms {
wait = self.retry_max_timeout_ms;
break;
}
}
let clamped = wait
.max(self.retry_min_timeout_ms)
.min(self.retry_max_timeout_ms);
std::time::Duration::from_millis(clamped)
}
}
fn clamp_u32(v: u64) -> u32 {
v.min(u64::from(u32::MAX)) as u32
}