pub struct ShapeStats {
pub classes: Vec<ClassStats>,
pub default_class: ClassStats,
pub unshapeable: ClassStats,
pub objects_seen: u64,
pub bytes_shaped: u64,
pub objects_expired: u64,
pub streams_reset_by_shaping: u64,
pub streams_with_mixed_classes: u64,
pub uplink: DirectionStats,
pub downlink: DirectionStats,
}Expand description
Shaping statistics for one session.
Zero-valued on any session with no ShapeProfile, which is what makes
this session shaped nothing a falsifiable claim rather than a promise.
Reported separately from Counters so that crate’s whole-struct == Counters::default() assertions keep meaning what they mean.
Read through
ProxySession::shape_stats.
The session totals appear twice: flat, summed over the whole session,
and again under Self::uplink and Self::downlink for one leg
each. The flat figure is the sum of the two by construction, so the two
forms can never disagree — pick the leg when the question is which side
stalled, and the aggregate when it is whether the profile ran at all.
Every field here is written. Two were not until recently — the
Duration totals on ClassStats, which were calibration figures and
are gone; that type says why there is no duration among these at all. A
zero row is still reported, never omitted — a class that saw nothing is
present and empty, which is the difference between a starved class and a
mis-typed one.
Fields§
§classes: Vec<ClassStats>One entry per configured class, in ShapeProfile::classes order.
default_class: ClassStatsUnits that matched no rule.
unshapeable: ClassStatsUnits with no object metadata at all: subgroup and fetch stream
headers, oversized passthrough objects, bypassed streams — every
fetch stream on drafts 15-19, which have no fetch object codec.
A separate row from Self::default_class, and the distinction is
the point: the default row is the rules saw this unit and none claimed
it, this row is no rule could have seen it. Merging them would make a
mis-aimed matcher indistinguishable from a stream the framer cannot
address.
These bytes are not paced: they charge no bucket, so a class rate can be exceeded by exactly one oversized object.
objects_seen: u64Hook-visible units the classifier saw.
Objects only. A stream header is counted in Self::bytes_shaped
and in Self::unshapeable, and not here.
bytes_shaped: u64Bytes the shaper accounted for — every byte it saw, whether a bucket
granted it, a policy dropped it, or it was unshapeable.
Deliberately not bytes that passed through a bucket: the
unshapeable row never touches a bucket, and the conservation identity
this total exists for — Σ classes(delivered + dropped) + default + unshapeable == bytes_shaped — has to hold across that row too, or bytes
the shaper declined to shape would vanish from the accounting.
objects_expired: u64Objects whose max_hold elapsed under Expiry::ResetStream.
Zero under the default Expiry::Deliver, which has no producer.
streams_reset_by_shaping: u64Destination streams abandoned by an overflow or expiry policy.
streams_with_mixed_classes: u64Streams on which two units resolved to different classes.
Head-gating means such a stream’s throughput is decided by whichever class is at the head, so without this count configured shaping and head-of-line blocking are indistinguishable from outside.
uplink: DirectionStatsThe same totals for the client’s traffic on its way to the relay.
Every flat total above is this plus Self::downlink, term by
term. Read a leg when the question is which side stalled; read the
aggregate when it is did the profile do anything at all. A session
shaping only one leg reports the other as all zeros, which is an
answer rather than an absence.
downlink: DirectionStatsThe same totals for the relay’s traffic on its way to the client.
Trait Implementations§
Source§impl Clone for ShapeStats
impl Clone for ShapeStats
Source§fn clone(&self) -> ShapeStats
fn clone(&self) -> ShapeStats
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more