pub struct Pacer { /* private fields */ }Expand description
A token bucket in bits, refilled from elapsed time.
Unlike upstream’s rate.Limiter, nothing here reads a clock: the budget is a pure function of
the instants handed in. That is what makes a release schedule reproducible in a test rather
than merely eventually-correct — pion cannot assert its own schedule without a fake clock.
Implementations§
Source§impl Pacer
impl Pacer
Sourcepub fn new(bits_per_second: f64) -> Self
pub fn new(bits_per_second: f64) -> Self
A bucket paced at bits_per_second, starting full.
Starting full rather than empty lets a connection send immediately instead of waiting out one burst’s worth of accumulation, which is what upstream’s limiter does too.
Sourcepub fn with_burst_bits(self, burst_bits: f64) -> Self
pub fn with_burst_bits(self, burst_bits: f64) -> Self
Override the burst size, in bits.
A burst set here is kept across rate changes. Deriving it from the rate is only a default; once the caller has said how much it is willing to release at once, an estimator raising the rate must not quietly widen that.
Sourcepub fn target_bitrate(&self) -> f64
pub fn target_bitrate(&self) -> f64
The rate currently being paced at, in bits per second.
Sourcepub fn set_target_bitrate(&mut self, bits_per_second: f64)
pub fn set_target_bitrate(&mut self, bits_per_second: f64)
Change the rate.
Synchronous and immediate, because this is what a bandwidth estimator drives: it computes a new target and the very next release must respect it. Accumulated budget is kept but clamped to the new burst, so lowering the rate cannot leave a large budget behind that would let a burst out at the old rate.
A burst set through Pacer::with_burst_bits survives this; only a burst that was derived
from the rate follows the rate.
Sourcepub fn can_afford(&self, bits: f64) -> bool
pub fn can_afford(&self, bits: f64) -> bool
Whether bits can be sent now.
Sourcepub fn consume(&mut self, bits: f64)
pub fn consume(&mut self, bits: f64)
Spend bits from the budget.
The budget is allowed to go negative on a packet larger than a full burst; otherwise such a packet could never be sent at all, and a stalled queue is worse than a momentary overshoot.
Sourcepub fn time_until_affordable(&self, bits: f64) -> Option<Duration>
pub fn time_until_affordable(&self, bits: f64) -> Option<Duration>
How long until bits becomes affordable.
Duration::ZERO when it already is. At a zero rate nothing ever becomes affordable, which
the caller must treat as “no deadline” rather than waiting forever.
Sourcepub fn affordable_at(&self, bits: f64) -> Option<Instant>
pub fn affordable_at(&self, bits: f64) -> Option<Instant>
The instant bits becomes affordable, given the last refill.
Sourcepub fn budget_bits(&self) -> f64
pub fn budget_bits(&self) -> f64
The available budget, in bits.
Sourcepub fn can_release(&self, bits: f64) -> bool
pub fn can_release(&self, bits: f64) -> bool
Whether bits may be released now.
A packet larger than a full burst can never be afforded — the budget caps at the burst — so it is released once the budget has refilled to that cap, which is as long as waiting can possibly help. Gating on a full budget rather than releasing unconditionally is what keeps a run of oversized packets paced: each drives the budget negative and the next must wait for it to recover, so they leave at the target rate instead of all at once.
Sourcepub fn releasable_at(&self, bits: f64) -> Option<Instant>
pub fn releasable_at(&self, bits: f64) -> Option<Instant>
The instant bits may be released, per Pacer::can_release.
Sourcepub fn burst_bits(&self) -> f64
pub fn burst_bits(&self) -> f64
The maximum the budget can accumulate to, in bits.
Anything larger than this can never be afforded by waiting, however long the wait — the
budget caps here — which is why release is asked for through Pacer::can_release rather
than Pacer::can_afford.