pub struct Backoff { /* private fields */ }Expand description
A backoff policy: a base curve plus a jitter mode and a delay ceiling.
Construct with constant, linear, or
exponential, then tune with
with_max and with_jitter. It is
usable on its own — pair it with Retry, or call
iter and drive your own loop.
§Examples
use std::time::Duration;
use throttle_net::{Backoff, Jitter};
// Exponential from 50ms, doubling, capped at 5s, with full jitter.
let backoff = Backoff::exponential(Duration::from_millis(50), 2.0)
.with_max(Duration::from_secs(5))
.with_jitter(Jitter::Full);
let mut delays = backoff.iter();
let first = delays.next_delay();
assert!(first <= Duration::from_millis(50)); // full jitter: in [0, 50ms]Implementations§
Source§impl Backoff
impl Backoff
Sourcepub fn constant(delay: Duration) -> Self
pub fn constant(delay: Duration) -> Self
A fixed delay on every attempt, with no jitter.
§Examples
use std::time::Duration;
use throttle_net::Backoff;
let mut delays = Backoff::constant(Duration::from_millis(200)).iter();
assert_eq!(delays.next_delay(), Duration::from_millis(200));
assert_eq!(delays.next_delay(), Duration::from_millis(200));Sourcepub fn linear(initial: Duration, increment: Duration) -> Self
pub fn linear(initial: Duration, increment: Duration) -> Self
A delay that grows by increment each attempt: initial, initial + increment, initial + 2*increment, … capped at the maximum.
§Examples
use std::time::Duration;
use throttle_net::Backoff;
let mut delays = Backoff::linear(Duration::from_millis(100), Duration::from_millis(100)).iter();
assert_eq!(delays.next_delay(), Duration::from_millis(100));
assert_eq!(delays.next_delay(), Duration::from_millis(200));
assert_eq!(delays.next_delay(), Duration::from_millis(300));Sourcepub fn exponential(initial: Duration, factor: f64) -> Self
pub fn exponential(initial: Duration, factor: f64) -> Self
A delay that multiplies by factor each attempt: initial, initial * factor, initial * factor^2, … capped at the maximum.
A factor of 2.0 doubles each time. Non-finite or sub-one factors are
accepted but make the curve flat or shrinking; pair with jitter for the
usual behavior.
§Examples
use std::time::Duration;
use throttle_net::Backoff;
let mut delays = Backoff::exponential(Duration::from_millis(100), 2.0).iter();
assert_eq!(delays.next_delay(), Duration::from_millis(100));
assert_eq!(delays.next_delay(), Duration::from_millis(200));
assert_eq!(delays.next_delay(), Duration::from_millis(400));Sourcepub fn with_max(self, max: Duration) -> Self
pub fn with_max(self, max: Duration) -> Self
Returns a copy with the delay ceiling set to max. No delay this backoff
produces will exceed it.
Sourcepub fn with_jitter(self, jitter: Jitter) -> Self
pub fn with_jitter(self, jitter: Jitter) -> Self
Returns a copy with the jitter mode set.
Sourcepub fn iter(&self) -> BackoffIter ⓘ
pub fn iter(&self) -> BackoffIter ⓘ
Starts a delay sequence, seeded from process entropy.
Each call returns an independent BackoffIter with its own random
state, so two retry loops sharing one policy still jitter independently.
The seed mixes a per-call counter with the wall clock under std; under
no_std it is counter-only (still distinct per iterator within a run). For
a fully reproducible sequence, use iter_seeded.
Sourcepub fn iter_seeded(&self, seed: u64) -> BackoffIter ⓘ
pub fn iter_seeded(&self, seed: u64) -> BackoffIter ⓘ
Starts a delay sequence with an explicit seed, for deterministic, reproducible tests.
§Examples
use std::time::Duration;
use throttle_net::{Backoff, Jitter};
let backoff = Backoff::exponential(Duration::from_millis(10), 2.0)
.with_jitter(Jitter::Full);
// The same seed always yields the same sequence.
let a: Vec<_> = (0..5).scan(backoff.iter_seeded(7), |it, _| Some(it.next_delay())).collect();
let b: Vec<_> = (0..5).scan(backoff.iter_seeded(7), |it, _| Some(it.next_delay())).collect();
assert_eq!(a, b);