use super::jitter::jitter_spins;
use super::{Backoff, spin};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ExponentialBackoff {
base_spins: u32,
max_spins: u32,
#[cfg(feature = "rand")]
jitter: Option<u32>, #[cfg(not(feature = "rand"))]
jitter: Option<(u64, u32)>, }
impl ExponentialBackoff {
#[cfg(feature = "rand")]
#[must_use]
pub const fn new(base_spins: u32, max_spins: u32, jitter: Option<u32>) -> Self {
Self {
base_spins,
max_spins,
jitter,
}
}
#[cfg(not(feature = "rand"))]
#[must_use]
pub const fn new(base_spins: u32, max_spins: u32, jitter: Option<(u64, u32)>) -> Self {
Self {
base_spins,
max_spins,
jitter,
}
}
pub(in crate::kairos) const fn spins(&self, attempt: u32) -> u32 {
let shift = attempt.saturating_sub(1);
let shift = if shift > 31 { 31 } else { shift };
let scaled = self.base_spins.saturating_mul(1u32 << shift);
if scaled < self.max_spins {
scaled
} else {
self.max_spins
}
}
}
impl Backoff for ExponentialBackoff {
fn backoff(&self, attempt: u32) {
spin(
self.spins(attempt)
.saturating_add(jitter_spins(self.jitter, attempt)),
);
}
}