#[non_exhaustive]pub struct BucketConfig {
pub name: String,
pub rate_bps: Option<u64>,
pub burst_bytes: u64,
pub ceil_bps: Option<u64>,
}Expand description
A named token bucket. One per class, or shared by several.
#[non_exhaustive] with a Default, exactly as
EgressConfig is. Without the Default
an integration-test crate could not construct one at all, because
struct-expression and functional-update syntax are both illegal outside
the defining crate — and note that ..BucketConfig::default() is one of
the two illegal forms (E0639), so an outside caller assigns per field
on a ::default() binding. See the module doc on
shape for the full statement. The default is an
unnamed, unlimited bucket.
§The written form requires name and burst_bytes
The two rate fields default to absent, which means unlimited and is a
sensible thing to leave out. The other two are required, and
burst_bytes is the interesting one: its Rust default is 0, a depth
that can cover no object at all, and a bucket that inherits it delivers
every unit at its max_hold clamp at a throughput bearing no relation to
the rate beside it. That failure is quiet — the run looks rate-limited,
because it is, just not by the number in the file — so the written form
makes the author state the depth rather than inherit the one value that
cannot work. See BucketConfig::burst_bytes.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.name: StringThe name a ClassRule refers to. Must be unique
across the profile’s buckets, and a class naming a bucket that is
not present is rejected by
ShapeProfile::try_new.
rate_bps: Option<u64>Sustained rate in bytes per second.
None means unlimited — an explicitly unshaped class, which is not
the same as no class: it still has a name, its own statistics, and
its own place in the discipline. charge answers
Grant::Now for every unit, whatever its size, and touches no
state.
Some(0) is legal and distinct: the bucket never refills, so
after the initial burst_bytes are spent no unit is ever grantable
from tokens. charge answers Grant::Never rather than a
refill instant, because there is no refill instant to compute and
arming a release timer at an unreachable one would arm a timer that
never fires. The caller supplies the deadline instead — the unit’s
max_hold clamp — so under the default
Expiry::Deliver a 0-bps class does deliver,
at max_hold, clamped, reporting Impairment{HoldClamped}.
A zero rate is checked before the burst, so a deliberately stopped
class answers Grant::Never and never Grant::LargerThanBurst. The
distinction is the whole value of the second variant: I asked for no
traffic is a configuration working, and I asked for a rate and my
burst cannot cover one object is a configuration that silently is not.
The consequence is binding on every fixture: a 0-bps class delivers
zero bytes is a statement about a sampling window, not a property. A
test that relies on starvation must pin
QueueConfig::max_hold explicitly so
the margin between the assertion and the delivery is visible in the
fixture rather than inherited from a default the test never names.
burst_bytes: u64Bytes the bucket may accumulate while idle, and therefore the
largest unit it can ever grant from tokens: a unit larger than
burst_bytes can never be covered, however long the caller waits.
Set this to at least one object. The default is 0, which
cannot cover anything, and the failure it produces is quiet: with no
unit ever grantable, every object leaves at its max_hold clamp
instead of at rate_bps, so the measured throughput is
depth / max_hold and bears no relation to the rate that was
written down. Measured, at rate_bps: Some(1_000_000) with
burst_bytes: 100 and 1000-byte objects: delivery landed on the
clamp exactly, at a rate the configuration never names.
charge answers Grant::LargerThanBurst for that case rather
than folding it into Grant::Never, so the caller can report it as
the misconfiguration it is instead of as the ordinary rate limiting
it is indistinguishable from. It cannot be rejected when the profile
is built: ShapeProfile::try_new has
the burst but not the object sizes, and the sizes are what decide.
ceil_bps: Option<u64>Optional ceiling for borrowing above rate_bps.
Reserved. The scheduler accepts this field and never borrows, with no
diagnostic — the frozen ShapeError has no variant it could land
in. A profile setting ceil_bps above rate_bps measures a flat
rate_bps; this sentence is the whole of the warning.
Trait Implementations§
Source§impl Clone for BucketConfig
impl Clone for BucketConfig
Source§fn clone(&self) -> BucketConfig
fn clone(&self) -> BucketConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more