#[non_exhaustive]pub enum ShapeError {
DuplicateClassName {
name: String,
},
UnknownBucket {
class: String,
bucket: String,
},
EgressSideInMatcher {
class: String,
},
ZeroWeight {
class: String,
},
EmptyQueue,
NoClasses,
InertMatcher {
class: String,
key: &'static str,
},
}Expand description
Why a ShapeProfile could not be built.
#[non_exhaustive] and no Default: nobody constructs an error, and a
later release adding a further reason must not be a breaking change.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
DuplicateClassName
Two classes share a name. Class names index the stats, so they must be unique or the stats are unattributable.
UnknownBucket
A class names a bucket that is not in buckets.
Fields
bucket: StringThe bucket name that matches no BucketConfig.
EgressSideInMatcher
A matcher’s side is an egress label. Hook sites only ever see
ClientToProxy / RelayToProxy, so such a rule matches nothing —
rejected here rather than left to look like a working rule that
never fires.
ZeroWeight
Discipline::WeightedRoundRobin with a zero weight: a class that
can never be scheduled.
EmptyQueue
QueueConfig::depth_objects or QueueConfig::depth_bytes is
zero, so the queue could admit nothing.
NoClasses
The profile declares no class rules, so it is a shaping profile that shapes nothing.
Every unit such a profile sees falls to Class::Default, which is
unpaced: no bucket claims it, no discipline arbitrates it and the
queue releases it as soon as it reaches the head. A session
configured with one therefore frames every object — because a profile
arms framing on its own — pays for the classification and the queue,
reports itself as shaping, and delivers at line rate. Nothing in
crate::shape::ShapeStats distinguishes it from a profile whose
classes never matched.
§It would also reach further than the session that carried it
A proxy sizes its class rows once, from the first shaped session it accepts, because a class is an index into the class list of the scheduler that produced it and rows that could be resized underneath a running session would relabel every figure in them. A classless profile arriving first would have installed no rows at all, and every classed session accepted afterwards — for the life of the proxy — would have found rows it did not match and charged the default one: every number right, every label gone, unrecoverable without a restart. That is guarded a second time where the sizing happens, but the guard is a repair at the far end of the pipe; this is the profile never existing.
A caller who wants the queue policy and no pacing writes one class claiming everything, over a bucket with no rate — an explicitly unshaped class, which has a name and a row of its own and says in the configuration what a missing class list only implied.
InertMatcher
A Matcher key names an empty set of values, so the class can
never claim a unit — on any draft, from any traffic.
The three shapes this catches:
a RangeSet built from an inverted range (RangeSet::new drops
start > end, leaving an empty set whose contains is always
false), an empty Matcher::priority range such as 200..=100,
and Matcher::every_nth with n == 0.
Distinct from
ImpairmentKind::ShapeRuleUnmatchable,
and the distinction is when the answer exists: a rule keyed on a
field this draft does not carry can only be judged against a running
session, so it is reported; an empty value set is a property of the
configuration by itself, so it is rejected before a session starts.
Rejecting is strictly the better answer where it is available —
there is no run to read the report from.
Trait Implementations§
Source§impl Clone for ShapeError
impl Clone for ShapeError
Source§impl Debug for ShapeError
impl Debug for ShapeError
Source§impl Display for ShapeError
impl Display for ShapeError
impl Eq for ShapeError
Source§impl Error for ShapeError
impl Error for ShapeError
1.30.0 · Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()