pub trait ModuleHandler:
Send
+ Sync
+ 'static {
// Required method
fn handle<'life0, 'async_trait>(
&'life0 self,
ctx: RequestCtx,
body: Vec<u8>,
) -> Pin<Box<dyn Future<Output = HandlerOutcome> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
// Provided methods
fn on_hello_ack<'life0, 'life1, 'async_trait>(
&'life0 self,
_ack: &'life1 ModuleHelloAckBody,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn on_bind<'life0, 'life1, 'async_trait>(
&'life0 self,
_req: &'life1 RouteBindRequest,
) -> Pin<Box<dyn Future<Output = BindDecision> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn on_bound<'life0, 'life1, 'async_trait>(
&'life0 self,
_handle: &'life1 RouteHandle,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn health<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = HealthReport> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn on_route_gone<'life0, 'life1, 'async_trait>(
&'life0 self,
_handle: &'life1 RouteHandle,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
}Expand description
Trait implemented by a module for its business logic. The serve functions in this crate own all wire-protocol plumbing.
Required Methods§
Sourcefn handle<'life0, 'async_trait>(
&'life0 self,
ctx: RequestCtx,
body: Vec<u8>,
) -> Pin<Box<dyn Future<Output = HandlerOutcome> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn handle<'life0, 'async_trait>(
&'life0 self,
ctx: RequestCtx,
body: Vec<u8>,
) -> Pin<Box<dyn Future<Output = HandlerOutcome> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Handle a data-plane request on a route channel. Return a unary response, a
typed error, or stream interim events via RequestCtx::emit and return
HandlerOutcome::Streamed. Each request runs in its own task so one slow
handler cannot head-of-line-block another route.
Provided Methods§
Sourcefn on_hello_ack<'life0, 'life1, 'async_trait>(
&'life0 self,
_ack: &'life1 ModuleHelloAckBody,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_hello_ack<'life0, 'life1, 'async_trait>(
&'life0 self,
_ack: &'life1 ModuleHelloAckBody,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Called once after HELLO_ACK so the module can inspect the ack body for negotiated capabilities and any storage descriptor supplied by the daemon.
Sourcefn on_bind<'life0, 'life1, 'async_trait>(
&'life0 self,
_req: &'life1 RouteBindRequest,
) -> Pin<Box<dyn Future<Output = BindDecision> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_bind<'life0, 'life1, 'async_trait>(
&'life0 self,
_req: &'life1 RouteBindRequest,
) -> Pin<Box<dyn Future<Output = BindDecision> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Decide a route.bind. This hook is decision-only and must not emit route traffic.
Sourcefn on_bound<'life0, 'life1, 'async_trait>(
&'life0 self,
_handle: &'life1 RouteHandle,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_bound<'life0, 'life1, 'async_trait>(
&'life0 self,
_handle: &'life1 RouteHandle,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Called after an accepted bind ACK is queued and the handle is installed.
Sourcefn health<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = HealthReport> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn health<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = HealthReport> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Return cheap in-memory health for the module.
THE DEFAULT ASSERTS HEALTH ON BEHALF OF A MODULE THAT NEVER WROTE ANY. A module that has not implemented this is indistinguishable on the wire from one that measured itself and found nothing wrong – and the daemon acts on the difference, since a healthy report suppresses escalation while an absent implementation means nothing was ever checked.
It stays a default because health is genuinely optional: a module that advertises no health capability is never probed, so the value is unread for those. The hazard is the module that DOES advertise health and inherits this – it answers “ok” forever, including while wedged.
Per Health-Path-Rule v3 an implementation must derive its status mechanically from signals the dispatch path stamps (a monotonic heartbeat, oldest-queued age), never from its own opinion, and must not take a blocking lock, touch disk, or spawn a subprocess on this path. A health reply that execs queues behind the host’s slowest shared resource – which is exactly the resource degraded under the conditions being probed.
Sourcefn on_route_gone<'life0, 'life1, 'async_trait>(
&'life0 self,
_handle: &'life1 RouteHandle,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_route_gone<'life0, 'life1, 'async_trait>(
&'life0 self,
_handle: &'life1 RouteHandle,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
A route was torn down, rejected, or abandoned before its bind ACK was queued.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".