Skip to main content

gglib_core/retry/
jitter.rs

1//! Jitter source for [`decide`](super::decide).
2//!
3//! Kept separate from the policy so the policy itself stays a pure function of
4//! its arguments — tests inject an exact `jitter_unit` and never touch this.
5
6use std::time::{SystemTime, UNIX_EPOCH};
7
8/// A value in `[0.0, 1.0)` for use as `jitter_unit`.
9///
10/// The bar here is "decorrelates concurrent clients", not statistical
11/// uniformity: two processes would have to back off within the same nanosecond
12/// to collide. That is met without a dependency, which matters because the
13/// workspace already carries several `rand` versions and neither consumer of
14/// this needs a third.
15///
16/// [`decide`](super::decide) clamps whatever it receives, so a coarse clock on
17/// some platform can degrade the spread but cannot produce an invalid delay.
18#[must_use]
19pub fn jitter_unit() -> f64 {
20    let nanos = SystemTime::now()
21        .duration_since(UNIX_EPOCH)
22        .unwrap_or_default()
23        .subsec_nanos();
24    f64::from(nanos) / 1_000_000_000.0
25}