http-common/src/backoff.rs (41 lines of code) (raw):

// Copyright (c) Microsoft. All rights reserved. use std::time::Duration; use rand::Rng; pub const DEFAULT_BACKOFF: Backoff<4> = Backoff { pattern: [ BackoffInstance::from_secs(60, 10), BackoffInstance::from_secs(120, 20), BackoffInstance::from_secs(180, 30), BackoffInstance::from_secs(300, 30), ], }; pub struct Backoff<const N: usize> { pattern: [BackoffInstance; N], } impl<const N: usize> Backoff<N> { #[allow(clippy::unused_self, clippy::cast_possible_truncation)] pub fn max_retries(&self) -> u32 { N as u32 } /// Computes backoff for current try. Returns None if no retry attempts left pub fn get_backoff_duration(&self, current_attempt: u32) -> Option<Duration> { self.pattern .get(current_attempt as usize - 1) .map(BackoffInstance::backoff_duration) } } pub struct BackoffInstance { duration: Duration, max_jitter: Duration, } impl BackoffInstance { const fn from_secs(duration: u64, max_jitter: u64) -> Self { Self { duration: Duration::from_secs(duration), max_jitter: Duration::from_secs(max_jitter), } } fn backoff_duration(&self) -> Duration { let mut rng = rand::thread_rng(); let jitter_multiple = rng.gen_range(0.0..1.0); self.duration + self.max_jitter.mul_f32(jitter_multiple) } }