pub struct Backoff { /* private fields */ }Expand description
The reconnect delay schedule: doubling from an initial delay to a ceiling, and back to the start after a connection that delivered something.
A plain schedule, with no clock and no socket, so the doubling and the
ceiling can be checked as arithmetic. As statements interleaved with a
sleep and a live socket they could only be checked by timing a real
reconnect, so neither was, and a schedule pinned at its initial value would
have hammered an unwell host without failing a test.
The basis is one socket crate’s former copy (src/supervisor.rs),
identical to the copies three other socket crates carried. Each copy was
deleted for this one in Stories 4.6 to 4.8, and each crate that carried
one takes its schedule from here.
Two divergence rows stay with each venue:
- D6. What counts as a connection that delivered something follows the
venue’s liveness rule (D5): any frame, a decoded event, or a ping. The
call site decides and passes it to
after_connection_endedas abool. - D13.
polyoxide-core’sRetryConfig::backoffis a different schedule, jittered, for HTTP retries. The two are never unified.
use std::time::Duration;
use polyoxide_ws::Backoff;
let mut backoff = Backoff::new(Duration::from_millis(10), Duration::from_millis(30));
assert_eq!(backoff.take(), Duration::from_millis(10));
assert_eq!(backoff.take(), Duration::from_millis(20));
assert_eq!(backoff.take(), Duration::from_millis(30));
backoff.after_connection_ended(true);
assert_eq!(backoff.take(), Duration::from_millis(10));Implementations§
Source§impl Backoff
impl Backoff
Sourcepub fn new(initial: Duration, max: Duration) -> Self
pub fn new(initial: Duration, max: Duration) -> Self
A schedule starting at initial and doubling towards max.
Both are raised to MIN_BACKOFF first, and initial is then lowered
to max: a builder’s backoff(initial, max) takes the two
independently, and nothing stops a caller passing them the wrong way
round, which would otherwise wait the larger delay once before the
ceiling took effect.
Sourcepub fn take(&mut self) -> Duration
pub fn take(&mut self) -> Duration
The delay to wait before the next attempt, advancing the schedule. The one after it doubles, up to the ceiling, saturating rather than overflowing.
Sourcepub fn take_at_least(&mut self, floor: Duration) -> Duration
pub fn take_at_least(&mut self, floor: Duration) -> Duration
As take, but at least floor, clamped to the
ceiling: the wait a refused attempt asked for, such as its
Retry-After, may only extend the delay, never shorten it, and never
past the ceiling (DRIFT R11). The schedule advances as take’s does.
The rule is polyoxide-core’s for HTTP, where Retry-After only
extends the retry delay; the two schedules stay apart (D13).
Sourcepub fn after_connection_ended(&mut self, delivered: bool)
pub fn after_connection_ended(&mut self, delivered: bool)
Note that a connection ended, and whether it delivered anything.
Resetting on delivered rather than on a successful connect is what
stops a host that accepts and immediately closes from pinning the delay
at its initial value. A host that reliably delivers exactly one frame
before dying still resets the schedule each time; most unhealthy hosts
fail before delivering anything.