pub struct CanaryController { /* private fields */ }Expand description
The per-generation canary analysis controller (DW-091). Compiled
once per config generation from the canary_analysis blocks on
service splits and AI model aliases; shared via Arc from the
dataplane generation. record_outcome runs on the response path
and evaluate runs on the background CanaryRunner loop.
Implementations§
Source§impl CanaryController
impl CanaryController
Sourcepub fn new() -> Self
pub fn new() -> Self
New empty controller (no canary groups). The fast path:
record_outcome and evaluate are no-ops.
Sourcepub fn compile(gateway: &Gateway, obs: Option<Arc<Observability>>) -> Self
pub fn compile(gateway: &Gateway, obs: Option<Arc<Observability>>) -> Self
Compile the controller from a gateway’s service splits and AI
model aliases. Only services/aliases with an enabled
canary_analysis block contribute a group. The observability
handle wires the metric families; pass None for direct
unit-test construction (metrics are then a no-op).
Sourcepub fn compile_with_clock(
gateway: &Gateway,
obs: Option<Arc<Observability>>,
now_secs: fn() -> u64,
) -> Self
pub fn compile_with_clock( gateway: &Gateway, obs: Option<Arc<Observability>>, now_secs: fn() -> u64, ) -> Self
Self::compile with a caller-supplied second clock (Unix
epoch). Intended for tests that need to advance time
deterministically (the same pattern as
AdaptiveController::compile_with_clock); production keeps the
system clock via Self::compile.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Whether any canary group is compiled in at all (the fast path: configs with no canary_analysis skip the per-request record_outcome entirely).
Sourcepub fn record_outcome(
&self,
group_name: &str,
is_canary: bool,
status: u16,
latency_ms: f64,
)
pub fn record_outcome( &self, group_name: &str, is_canary: bool, status: u16, latency_ms: f64, )
Record one upstream outcome for group_name (DW-091):
increment the appropriate side’s request/error counters and
add the latency sample. A no-op when the group has no
canary_analysis. is_canary selects the side (true = canary,
false = baseline); status is the upstream HTTP status (5xx
counts as an error); latency_ms is the upstream round-trip
in milliseconds.
Sourcepub fn evaluate(&self) -> Vec<CanaryAction>
pub fn evaluate(&self) -> Vec<CanaryAction>
Evaluate all groups and return the actions the runner should
apply. Each action carries the recommended new canary weight.
The runner applies them and emits events; the controller’s
last_adjustment and current_canary_weight are updated by
Self::note_applied.
Sourcepub fn note_applied(&self, action: &CanaryAction)
pub fn note_applied(&self, action: &CanaryAction)
Note that an action was successfully applied (the runner calls
this after apply_*_weights returns true). Updates the
group’s last_adjustment and current_canary_weight, and
records the promotion/rollback metric.
Sourcepub fn current_canary_weight(&self, group: &str) -> Option<u64>
pub fn current_canary_weight(&self, group: &str) -> Option<u64>
The current transient canary weight for a group (tests /
diagnostics). Returns None when the group does not exist.
Sourcepub fn total_weight(&self, group: &str) -> Option<u64>
pub fn total_weight(&self, group: &str) -> Option<u64>
The total weight for a group (tests / diagnostics).
Trait Implementations§
Source§impl Debug for CanaryController
impl Debug for CanaryController
Auto Trait Implementations§
impl Freeze for CanaryController
impl !RefUnwindSafe for CanaryController
impl Send for CanaryController
impl Sync for CanaryController
impl Unpin for CanaryController
impl !UnwindSafe for CanaryController
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
§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