actr_framework/
dispatcher.rs

1//! MessageDispatcher trait - Message routing and dispatching
2
3use actr_protocol::{ActorResult, RpcEnvelope};
4use async_trait::async_trait;
5use bytes::Bytes;
6
7use crate::{Context, Workload};
8
9/// MessageDispatcher - Message dispatcher interface
10///
11/// Responsible for routing incoming message envelopes to corresponding handler methods.
12///
13/// # Design Characteristics
14///
15/// - **Static routing**: Implemented via compile-time match statements, no runtime lookup overhead
16/// - **Zero-sized type (ZST)**: Router itself occupies no memory
17/// - **Code generation**: Implementation is auto-generated by `actr-cli` codegen
18///
19/// # Code Generation Example
20///
21/// ```rust,ignore
22/// // Generated by code generator
23/// pub struct EchoServiceRouter<T: EchoServiceHandler>(PhantomData<T>);
24///
25/// #[async_trait]
26/// impl<T: EchoServiceHandler> MessageDispatcher for EchoServiceRouter<T> {
27///     type Workload = EchoServiceWorkload<T>;
28///
29///     async fn dispatch<C: Context>(
30///         workload: &Self::Workload,
31///         envelope: RpcEnvelope,
32///         ctx: &C,
33///     ) -> ActorResult<Bytes> {
34///         match envelope.route_key.as_str() {
35///             "echo.EchoService.Echo" => {
36///                 let req = EchoRequest::decode(&*envelope.payload)?;
37///                 let resp = workload.0.echo(req, ctx).await?;
38///                 Ok(resp.encode_to_vec().into())
39///             }
40///             _ => Err(ProtocolError::Actr(ActrError::UnknownRoute {
41///                 route_key: envelope.route_key.to_string()
42///             }))
43///         }
44///     }
45/// }
46/// ```
47#[async_trait]
48pub trait MessageDispatcher: Send + Sync + 'static {
49    /// Associated Workload type
50    type Workload: Workload<Dispatcher = Self>;
51
52    /// Dispatch message to corresponding handler method and execute full request-response cycle
53    ///
54    /// # Responsibilities
55    ///
56    /// 1. **Routing**: Select handler method based on `envelope.route_key`
57    /// 2. **Decoding**: Deserialize payload into concrete message type
58    /// 3. **Dispatching**: Invoke workload's business logic method
59    /// 4. **Encoding**: Serialize response into bytes
60    ///
61    /// # Parameters
62    ///
63    /// - `workload`: Workload instance (contains user business logic)
64    /// - `envelope`: Message envelope (contains route_key and payload)
65    /// - `ctx`: Execution context (generic, supports any Context implementation)
66    ///
67    /// # Returns
68    ///
69    /// Returns serialized response bytes
70    async fn dispatch<C: Context>(
71        workload: &Self::Workload,
72        envelope: RpcEnvelope,
73        ctx: &C,
74    ) -> ActorResult<Bytes>;
75}