pub struct Random { /* private fields */ }Expand description
Uniform (optionally weight-biased) random backend selection.
The RNG is seeded once, at construction, and never from an ambient source
on the selection hot path — but, unlike Rendezvous/Maglev, it is NOT seeded from the shared
DEFAULT_HASH_SEED constant. Rendezvous/Maglev feed their seed into
a pure, stateless hash function (hash_backend): same (seed, key, addr) in, same score out, independent of call history, so sharing the
seed fleet-wide is exactly the point — it is what makes the same affinity
key land on the same backend across workers and restarts.
Random feeds its seed into a stateful, advancing StdRng, where the
n-th pick depends on the whole call history. Seeding that from a shared
compile-time constant would make every worker, on every cold start, with
an identically-ordered backend list, draw from a bit-for-bit identical
keystream — so every fresh worker’s first pick over N equal-weight
backends would be the same backend index, fleet-wide, on every restart:
exactly the correlated-load event uniform selection exists to prevent,
arriving at the worst possible moment (a synchronised redeploy, when every
worker’s call counter resets together and initial load is otherwise
indistinguishable). So the seed is the caller’s, and the production caller
draws it from an OS-seeded generator: BackendMap::new seeds its own
generator from the OS once, at construction, and hands every cluster’s
policy a seed drawn from it (crate::backends::BackendMap, #1684). Each
worker’s keystream is therefore independent, as with the thread-local
rng() this replaced, while a simulator that builds the map with
BackendMap::with_seed gets a fixed, reproducible sequence (mirrors
quinn-proto’s rng_seed construction shape).
This does NOT make Random return a fixed backend: next_available_backend
advances the internal RNG on every call, so a sequence of calls still
draws a well-distributed spread of backends. “Random” here means
“statistically spread, and — given with_seed — reproducible for a fixed
seed and exact call sequence” — not “constant”. Two instances built with
with_seed on the same seed and driven through the same sequence of
backend sets reproduce the same sequence of picks (what makes this
testable); a single instance called repeatedly keeps drawing fresh values
from its advancing RNG state, exactly like a real RNG would; two lists of
one map, or two maps, draw from independent keystreams.