pub struct Policy {
pub name: String,
pub rate_limit: Option<RateLimit>,
pub rate_limits: Vec<RateLimitRule>,
pub timeouts: Option<Timeouts>,
pub dry_run: bool,
pub token_budget: Option<TokenBudget>,
pub anomaly: Option<AnomalyPolicy>,
pub adaptive: Option<AdaptiveRateLimit>,
}Expand description
Named reusable rule bundle (rate limit, timeouts, …); attachable at several scopes. Plugin-backed phases arrive with the M3 plugin system.
Fields§
§name: String§rate_limit: Option<RateLimit>§rate_limits: Vec<RateLimitRule>Stacked GCRA rate-limit rules (DW-017). Each rule stacks one or
more windows (e.g. s AND hour); a request is admitted only if
EVERY window of EVERY applicable rule allows it. The legacy
single-window rate_limit field above still applies when set (see
its mapping in the rate-limiter module docs); use rate_limits
for new configs.
timeouts: Option<Timeouts>§dry_run: boolMonitor mode (DW-041) for this bundle’s rate-limit rules: they
still EVALUATE (their GCRA buckets advance exactly as if
enforcing, so denial rates reflect what enforcement would do),
but a request they would deny is LOGGED and counted
(dwara_policy_dry_run_total{phase="rate_limit"} + a
dwara::policy warn event) and PROCEEDS — no 429, and none of
the rule’s X-RateLimit-* headers on the response. LIVE policies
attached to the same request still enforce: the flag mutes only
this bundle’s own denials. The flag sits on the named bundle (not
on each policies: [...] attachment list entry) because rate
limits attach BY NAME at the five precedence levels — marking the
bundle dries every attachment of it uniformly. Timeouts carry no
rejection and are unaffected.
token_budget: Option<TokenBudget>AI token budget (DW-078): caps provider-reported tokens per
minute and/or priced cost per UTC day for the budget holder.
Distinct from every rule above: those count REQUESTS, this
counts TOKENS. Resolution follows the frozen precedence chain
(consumer > route > service > listener > global) with the MOST
SPECIFIC level’s budget governing (a limit-of-totals, not an
AND-composed rule). scope: consumer (default) keys the budget
to each attaching consumer; scope: policy makes one SHARED
(team) budget keyed by the policy name. Consumers with no
binding budget are unlimited.
anomaly: Option<AnomalyPolicy>Anomaly scoring (DW-090): lightweight statistical detection of
abusive request patterns (header entropy, request-shape outliers).
When enabled, every matched request is scored against the
configured signals; a score at or above threshold is blocked
(403 anomaly_blocked) unless dry_run is set (scored and
logged, request proceeds). Resolution follows the frozen
precedence chain (consumer > route > service > listener > global);
every level with an attachment applies and the applicable rules
AND together. Absent (the default): no anomaly scoring.
adaptive: Option<AdaptiveRateLimit>Adaptive + origin-driven rate-limit tuning (DW-089): an EWMA of
upstream error rate and latency dynamically scales this policy’s
rate-limit quotas, and upstream-originated signals (Retry-After)
trigger an immediate backoff for the advertised window. The
adaptive factor is bounded [min_factor, max_factor] (never 0,
never unbounded); tightening under stress is faster than relaxing
when healthy (asymmetric). Absent (the default): no adaptive
tuning, the policy’s quotas apply as configured.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Policy
impl<'de> Deserialize<'de> for Policy
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl JsonSchema for Policy
impl JsonSchema for Policy
Source§fn schema_id() -> Cow<'static, str>
fn schema_id() -> Cow<'static, str>
Source§fn json_schema(generator: &mut SchemaGenerator) -> Schema
fn json_schema(generator: &mut SchemaGenerator) -> Schema
Source§fn inline_schema() -> bool
fn inline_schema() -> bool
$ref keyword. Read moreimpl StructuralPartialEq for Policy
Auto Trait Implementations§
impl Freeze for Policy
impl RefUnwindSafe for Policy
impl Send for Policy
impl Sync for Policy
impl Unpin for Policy
impl UnwindSafe for Policy
Blanket Implementations§
§impl<T> AnyExt for T
impl<T> AnyExt for T
§fn downcast_ref<T>(this: &Self) -> Option<&T>where
T: Any,
fn downcast_ref<T>(this: &Self) -> Option<&T>where
T: Any,
T behind reference§fn downcast_mut<T>(this: &mut Self) -> Option<&mut T>where
T: Any,
fn downcast_mut<T>(this: &mut Self) -> Option<&mut T>where
T: Any,
T behind mutable reference§fn downcast_rc<T>(this: Rc<Self>) -> Result<Rc<T>, Rc<Self>>where
T: Any,
fn downcast_rc<T>(this: Rc<Self>) -> Result<Rc<T>, Rc<Self>>where
T: Any,
T behind Rc pointer§fn downcast_arc<T>(this: Arc<Self>) -> Result<Arc<T>, Arc<Self>>where
T: Any,
fn downcast_arc<T>(this: Arc<Self>) -> Result<Arc<T>, Arc<Self>>where
T: Any,
T behind Arc pointer§fn downcast_box<T>(this: Box<Self>) -> Result<Box<T>, Box<Self>>where
T: Any,
fn downcast_box<T>(this: Box<Self>) -> Result<Box<T>, Box<Self>>where
T: Any,
T behind Box pointer§fn downcast_move<T>(this: Self) -> Option<T>
fn downcast_move<T>(this: Self) -> Option<T>
Self to T,
useful only in generic context as a workaround for specializationSource§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T, X> CoerceTo<T> for Xwhere
T: CoerceFrom<X> + ?Sized,
impl<T, X> CoerceTo<T> for Xwhere
T: CoerceFrom<X> + ?Sized,
fn coerce_rc_to(self: Rc<X>) -> Rc<T>
fn coerce_box_to(self: Box<X>) -> Box<T>
fn coerce_ref_to(&self) -> &T
fn coerce_mut_to(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more