pub struct ProjectionRouter { /* private fields */ }Expand description
Event-stream dispatcher. Matches incoming events to registered
projections by TypeCode, enforces dedup + gap detection via
Projection::last_applied, and propagates observer state transitions.
Implementations§
Source§impl ProjectionRouter
impl ProjectionRouter
Sourcepub fn new() -> Self
pub fn new() -> Self
Build a router in the Passive state — promote to Active before
committing writes.
Sourcepub fn register(&mut self, projection: Box<dyn Projection>)
pub fn register(&mut self, projection: Box<dyn Projection>)
Register a projection.
Sourcepub fn state(&self) -> ObserverState
pub fn state(&self) -> ObserverState
Current observer state.
Sourcepub fn promote_to_active(&mut self) -> Result<(), ProjectionError>
pub fn promote_to_active(&mut self) -> Result<(), ProjectionError>
Transition to Active — fails if currently Draining.
Sourcepub fn evaluate_auto_promote(
&self,
manifest: &ManifestSnapshot,
primary_down_duration: Duration,
health: &MultiChannelHealth,
threshold_ready: bool,
) -> Option<PromotionDecision>
pub fn evaluate_auto_promote( &self, manifest: &ManifestSnapshot, primary_down_duration: Duration, health: &MultiChannelHealth, threshold_ready: bool, ) -> Option<PromotionDecision>
Evaluate the shell’s kms_auto_promote policy against three inputs:
the elapsed outage, the multi-channel KMS health quorum, and the
threshold-HSM share readiness.
Policy values:
kms_auto_promote | Decision matrix |
|---|---|
"manual" | Always Some(Wait) — operator drives the promotion manually. |
"after_60min" | Some(Promote) iff primary_down_duration >= 1h and the KMS health quorum has at least HF2_HEALTH_QUORUM_MIN channels healthy; otherwise Some(Wait). |
"threshold_hsm" | Some(Promote) iff threshold_ready (t-of-n shares collected); otherwise Some(Wait). |
| other | None — unrecognised policy string, operator intervention required. |
Returning None is conservative by design: callers treat unknown
policies as “do not auto-promote” and fall back to manual operator
action.
Sourcepub fn demote_to_passive(&mut self) -> Result<(), ProjectionError>
pub fn demote_to_passive(&mut self) -> Result<(), ProjectionError>
Transition to Passive. Used when ceding primary to a peer.
Sourcepub fn begin_draining(&mut self) -> Result<(), ProjectionError>
pub fn begin_draining(&mut self) -> Result<(), ProjectionError>
Transition to Draining. Terminal — no further state changes.
Sourcepub fn dispatch(
&mut self,
event: &EventRecord,
ctx: &ProjectionContext<'_>,
) -> Result<usize, ProjectionError>
pub fn dispatch( &mut self, event: &EventRecord, ctx: &ProjectionContext<'_>, ) -> Result<usize, ProjectionError>
Dispatch an event to every matching projection. Returns Ok(n)
where n is the number of projections that applied the event.
Only the Active state may dispatch — Passive and Draining
reject with ProjectionError::NotActive. The Passive rejection
is the production guardrail for active-passive HA: a secondary
observer that mistakenly accepts writes would create split-brain
rows in the PG-backed store. The dylint arkhe-trait-default-check
CI gate ensures the contract is honoured by every L2 deployment.