pub struct Dispatcher<P, Ctx, D> { /* private fields */ }Expand description
Builds a compile-time dispatch chain in its type parameter D.
The chain is unrolled in Self::sequential_dispatch or Self::dispatch.
Use Self::seq to add sequential handlers (&mut Ctx, !Send future) or
Self::on to add concurrent handlers (Ctx: Clone + Send, spawned as tasks).
Implementations§
Source§impl<P, Ctx, D> Dispatcher<P, Ctx, D>where
D: DispatchEvent<Ctx>,
impl<P, Ctx, D> Dispatcher<P, Ctx, D>where
D: DispatchEvent<Ctx>,
Sourcepub fn seq<Ev, F>(self, f: F) -> Dispatcher<P, Ctx, Intercept<Match<Ev, F>, D>>
pub fn seq<Ev, F>(self, f: F) -> Dispatcher<P, Ctx, Intercept<Match<Ev, F>, D>>
Register a sequential event handler.
- The handler signature is
AsyncFnMut(ev: Arc<{EventType}>, ctx: &mut Ctx) -> Result<StreamEvents, {ErrorType}> Ctxis whatever type you pass when creating the dispatcher withevents.into_local_dispatcher(ctx). It will be passed by a mutable reference into all handlers{Eventype}is one of the data structs defined incrate::events. Events are dispatched statically so this type links the handler to event. When handlers with the same{EvenType}are set multiple times the last one wins.{ErrorType}can be arbitrary but all handlers must share it and it must implementFrom<ClientError>.- Events are processed one at a time; handlers have exclusive
&mutaccess toCtx.
§Usage
- Set async fn
events.into_dispatcher(client)
.seq(contact_connected)
.sequential_dispatch()
.await;
async fn contact_connected(
ev: Arc<ContactConnected>,
ctx: &mut ws::Client,
) -> ClientResult<StreamEvents> { ... }- Set async closure by fully qualifying types
events.into_local_dispatcher(client)
.seq_fallback(async |ev, _| log::debug!("{ev:?}"))
.seq::<ContactConnected, _>(async |ev, &mut client| { ... })
.sequential_dispatch()
.await;- Set async closure by specifying closure argument type
events.into_local_dispatcher(client)
.seq_fallback(async |ev, _| log::debug!("{ev:?}"))
.seq(async |ev: Arc<ContactConnected>, &mut client| {
//...
})
.sequential_dispatch()
.await;Sourcepub async fn sequential_dispatch(
self,
) -> Result<(EventStream<P>, Ctx), D::Error>
pub async fn sequential_dispatch( self, ) -> Result<(EventStream<P>, Ctx), D::Error>
Dispatch events sequentially. Handlers block the event loop, allowing exclusive &mut Ctx
access. Returning StreamEvents::Break stops the dispatcher and returns the event stream
and ctx for further processing.
Produces a !Send future that can be used with tokio::task::LocalSet, on the main
tokio thread, or with a single-threaded runtime.
Sourcepub async fn sequential_dispatch_with_cancellation(
self,
token: CancellationToken,
) -> Result<(EventStream<P>, Ctx), D::Error>
Available on crate feature cancellation only.
pub async fn sequential_dispatch_with_cancellation( self, token: CancellationToken, ) -> Result<(EventStream<P>, Ctx), D::Error>
cancellation only.Like Self::sequential_dispatch but stops when token is cancelled. Token cancellation
is equivalent to returning StreamEvents::Break.
Source§impl<P, Ctx, D> Dispatcher<P, Ctx, D>where
P: 'static + EventParser,
Ctx: 'static + Send + Clone,
D: ConcurrentDispatchEvent<Ctx>,
D::Error: From<P::Error>,
impl<P, Ctx, D> Dispatcher<P, Ctx, D>where
P: 'static + EventParser,
Ctx: 'static + Send + Clone,
D: ConcurrentDispatchEvent<Ctx>,
D::Error: From<P::Error>,
Sourcepub fn on<Ev, F, Fut>(
self,
f: F,
) -> Dispatcher<P, Ctx, Intercept<Match<Ev, F>, D>>
pub fn on<Ev, F, Fut>( self, f: F, ) -> Dispatcher<P, Ctx, Intercept<Match<Ev, F>, D>>
Register a concurrent event handler.
- The handler signature is
AsyncFn(ev: Arc<{EventType}>, ctx: Ctx) -> Result<StreamEvents, {ErrorType}>; Ctxis whatever is passed into theinto_dispatchercall. It is cloned into every handler invocation{Eventype}is one of the data structs defined incrate::events. Events are dispatched statically so this type links the handler to event. When handlers with the same{EvenType}are set multiple times the last one wins.{ErrorType}can be arbitrary but all handlers must share it and it must implementFrom<ClientError>.- All handlers run as tokio tasks so events are processed concurrently(and in parallel on multithreaded runtimes).
§Usage
- Set async fn
events.into_dispatcher(client)
.on(contact_connected)
.dispatch()
.await;
async fn contact_connected(
ev: Arc<ContactConnected>,
ctx: ws::Client,
) -> ClientResult<StreamEvents> { ... }- Set async closure by fully qualifying types
events.into_dispatcher(client)
.fallback(async |ev, _| log::debug!("{ev:?}"))
.on::<ContactConnected, _, _>(async |ev, client| { ... })
.dispatch()
.await;- Set async closure by specifying closure argument type
events.into_dispatcher(client)
.fallback(async |ev, _| log::debug!("{ev:?}"))
.on(async |ev: Arc<ContactConnected>, client| { ... })
.dispatch()
.await;Sourcepub async fn dispatch(
self,
) -> Result<(EventStream<P>, Ctx, Vec<Event>), D::Error>
pub async fn dispatch( self, ) -> Result<(EventStream<P>, Ctx, Vec<Event>), D::Error>
Spawns handlers as tokio tasks. Handlers execute and resolve in arbitrary order.
StreamEvents::Break eventually stops the dispatcher after all in-flight handlers finish.
The returned EventStream filters should be reset via EventStream::accept_all if you
want to query the stream manually and process all events afterwards.
§Errors and panics
If a handler returns an error or panics, the dispatcher stops, waits for in-flight handlers to complete, then returns the first error or resumes the first panic.
Sourcepub async fn dispatch_with_cancellation(
self,
token: CancellationToken,
) -> Result<(EventStream<P>, Ctx, Vec<Event>), D::Error>
Available on crate feature cancellation only.
pub async fn dispatch_with_cancellation( self, token: CancellationToken, ) -> Result<(EventStream<P>, Ctx, Vec<Event>), D::Error>
cancellation only.Like Self::dispatch but stops when token is cancelled. Token cancellation behaviour
is equivalent to returning StreamEvents::Break.
Sourcepub async fn dispatch_sequentially(
self,
) -> Result<(EventStream<P>, Ctx), D::Error>
pub async fn dispatch_sequentially( self, ) -> Result<(EventStream<P>, Ctx), D::Error>
Runs concurrent handlers one at a time, producing a 'static + Send future.
Unlike Dispatcher::sequential_dispatch this clones Ctx per event (no &mut) and the
resulting future is Send. Use when handler execution order matters but you need a
sendable future, e.g. inside tokio::spawn.
Sourcepub async fn dispatch_sequentially_with_cancellation(
self,
token: CancellationToken,
) -> Result<(EventStream<P>, Ctx), D::Error>
Available on crate feature cancellation only.
pub async fn dispatch_sequentially_with_cancellation( self, token: CancellationToken, ) -> Result<(EventStream<P>, Ctx), D::Error>
cancellation only.Like Self::dispatch_sequentially but stops when token is cancelled.
Auto Trait Implementations§
impl<P, Ctx, D> Freeze for Dispatcher<P, Ctx, D>
impl<P, Ctx, D> !RefUnwindSafe for Dispatcher<P, Ctx, D>
impl<P, Ctx, D> !Send for Dispatcher<P, Ctx, D>
impl<P, Ctx, D> !Sync for Dispatcher<P, Ctx, D>
impl<P, Ctx, D> Unpin for Dispatcher<P, Ctx, D>
impl<P, Ctx, D> UnsafeUnpin for Dispatcher<P, Ctx, D>where
Ctx: UnsafeUnpin,
D: UnsafeUnpin,
impl<P, Ctx, D> !UnwindSafe for Dispatcher<P, Ctx, D>
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> 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