pub struct EventCtx<'inv, B = ()> { /* private fields */ }Expand description
Per-event decision point handed to
handle_persistent.
Generic over the handler’s
Batch accumulator B (defaulting
to () for handlers that never collect). See the module docs
for the semantics of the three entry verbs.
§Presence contract
A singleton subscriber is always on, and that presence is what
licenses its ephemeral subscription: ephemeral events cannot be replayed,
so only an always-present consumer may hear them. This ctx therefore has
no pausing verb — no pause_until, no staged chain.
Their absence is semantic, not an omission: a verb that suspends
consumption would contradict the property that defines the mode.
use obix::{EventCtx, Handled};
fn pause_it<'inv>(ctx: EventCtx<'inv>) -> Handled<'inv> {
// error[E0599]: no method named `pause_until` found for struct `EventCtx`
//
// A flow that pauses or stages is persistent-only by definition —
// host it as a keyed subscriber; a single static key is legitimate.
ctx.pause_until()
}The control for the negative test above — same signature, with a verb a
singleton ctx does have. If this stops compiling, the compile_fail
above has started passing for the wrong reason:
use obix::{EventCtx, Handled};
fn resolve_it<'inv>(ctx: EventCtx<'inv>) -> Handled<'inv> {
ctx.skip()
}Implementations§
Source§impl<'inv, B> EventCtx<'inv, B>
impl<'inv, B> EventCtx<'inv, B>
Sourcepub fn skip(self) -> Handled<'inv>
pub fn skip(self) -> Handled<'inv>
This event is not for me — no transaction is opened, an open batch op is left untouched, and the checkpoint advances lazily (piggybacked on the next flush, or persisted on the configured checkpoint interval).
Sourcepub fn collect_with(self, f: impl FnOnce(&mut B)) -> Handled<'inv>
pub fn collect_with(self, f: impl FnOnce(&mut B)) -> Handled<'inv>
Contribute to the pending batch’s accumulator — a pure memory write:
no transaction is opened and no statement is executed now. The runner
hands the accumulated batch to the handler’s
flush exactly once per batch
landing, inside the transaction that commits the checkpoint.
Collected work shares fate with its neighbors and must tolerate whole-batch replay: on a failed flush the events replay and their items are re-collected.
For Vec and HashMap accumulators the collect
sugar is usually more convenient.
Sourcepub async fn consume(
self,
) -> Result<IsolatedOp<'inv>, Box<dyn Error + Send + Sync>>where
B: Default,
pub async fn consume(
self,
) -> Result<IsolatedOp<'inv>, Box<dyn Error + Send + Sync>>where
B: Default,
Land the pending batch first (its collected items and its checkpoint,
at the last fully handled sequence), then hand back a fresh op: this
event is its own atomic unit, sharing no fate with history — and none
with the future either, since IsolatedOp only offers
commit.
This is the failure-isolation fence: if this event’s work fails, only this event replays.
Source§impl<'inv, T> EventCtx<'inv, Vec<T>>
impl<'inv, T> EventCtx<'inv, Vec<T>>
Sourcepub fn collect(self, item: T) -> Handled<'inv>
pub fn collect(self, item: T) -> Handled<'inv>
collect_with sugar for Vec accumulators:
append one item to the pending batch.
Source§impl<'inv, K, V, S> EventCtx<'inv, HashMap<K, V, S>>
impl<'inv, K, V, S> EventCtx<'inv, HashMap<K, V, S>>
Sourcepub fn collect(self, key: K, value: V) -> Handled<'inv>
pub fn collect(self, key: K, value: V) -> Handled<'inv>
collect_with sugar for HashMap accumulators:
keyed last-write-wins insert. Persistent events arrive in ascending
sequence, so within a batch this naturally keeps the newest item per
key — the coalescing fold (N updates per key → 1 flushed entry).
Auto Trait Implementations§
impl<'inv, B = ()> !RefUnwindSafe for EventCtx<'inv, B>
impl<'inv, B = ()> !Sync for EventCtx<'inv, B>
impl<'inv, B = ()> !UnwindSafe for EventCtx<'inv, B>
impl<'inv, B> Freeze for EventCtx<'inv, B>
impl<'inv, B> Send for EventCtx<'inv, B>
impl<'inv, B> Unpin for EventCtx<'inv, B>
impl<'inv, B> UnsafeUnpin for EventCtx<'inv, B>
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
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
Source§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
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> 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