pub struct NamespaceEventGate { /* private fields */ }Expand description
Per-connection gate deciding whether an event belongs to the authorized namespace, and what workflow type its workflow carries.
Verdicts are cached per workflow in a bounded LRU. The cache is sound
because a workflow’s owner namespace is recorded atomically with its
WorkflowStarted batch and never changes, and the publisher broadcasts
only after durable commit — so by the time any event for a workflow is
observed here, its ownership verdict is durable and final, and an evicted
entry that is later re-read always reproduces the same verdict.
The cache bound is derived from the configured
websocket.event_broadcast_capacity rather than introducing a new knob:
the engine-global broadcast channel retains at most that many events, so
any burst this connection can observe without lagging out references at
most that many distinct workflows. Sizing the LRU to the broadcast
capacity keeps every workflow of the largest possible in-flight window
cached; anything beyond it is cold traffic where an eviction costs one
re-read of immutable durable state.
Implementations§
Source§impl NamespaceEventGate
impl NamespaceEventGate
Sourcepub fn new(
resolver: NamespaceResolver,
namespace: String,
verdict_capacity: NonZeroUsize,
) -> Self
pub fn new( resolver: NamespaceResolver, namespace: String, verdict_capacity: NonZeroUsize, ) -> Self
Build a gate for one authorized namespace with a bounded verdict cache.
Sourcepub fn allow(&mut self, workflow_id: WorkflowId)
pub fn allow(&mut self, workflow_id: WorkflowId)
Pre-seed an allow verdict for a workflow whose ownership the namespace guard already verified (the per-workflow subscription target), so the hot path never re-reads history for it. The workflow type is captured lazily from the stream or a later attribution read; per-workflow subscriptions carry no type selector, so none is needed up front.
Sourcepub async fn admit(&mut self, event: &Event) -> Result<GateVerdict, ServerError>
pub async fn admit(&mut self, event: &Event) -> Result<GateVerdict, ServerError>
Decide whether event may be delivered to this connection.
GateVerdict::Filtered means the event’s workflow is foreign or
unknown to the authorized namespace. GateVerdict::Permitted carries
the workflow’s recorded type so selector filtering can run on the same
cached read that proved ownership.
A delivered WorkflowStarted event refreshes the cached type inline
(continue-as-new chains record each run’s type on its own
WorkflowStarted), so the cached type follows the stream’s own order
without extra reads. The initial durable read instead resolves the
head-of-history type at read time, which on a continue-as-new chain
can run ahead of an older delivered event for at most one event-loop
turn before the inline refresh self-heals it.
§Errors
Returns ServerError when the durable ownership source cannot be
read; callers must terminate the stream loudly rather than guessing.
Auto Trait Implementations§
impl !RefUnwindSafe for NamespaceEventGate
impl !UnwindSafe for NamespaceEventGate
impl Freeze for NamespaceEventGate
impl Send for NamespaceEventGate
impl Sync for NamespaceEventGate
impl Unpin for NamespaceEventGate
impl UnsafeUnpin for NamespaceEventGate
Blanket Implementations§
Source§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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request