下面显示的是英文原文。
FredPool
Ctx<keys::FredPool> hands a handler the broker's fred connection pool on every form, for a command whose answer it needs now.
The value is fred::clients::Pool, the pool the broker publishes through.
A command sent on it runs at once, and the handler reads its reply before it returns.
That is the difference from a pipelined command, which leaves after the handler, with the delivery's acknowledgement, and returns no reply.
The command methods come from fred's interface traits, such as fred::interfaces::KeysInterface, which the handler's file imports.
As the only Ctx key of a handler, FredPool names PoolContext, a context that carries the pool alone.
Beside a form's own key it reads that form's context: StreamContext, StreamBatchContext, PubSubContext or the pipelined PipelineContext.
There it goes after the form's key in the signature, because the first Ctx key names the handler's context.
A list handler, whose delivery carries no context of its own, takes the pool through PoolContext.
Example
Each order takes the next number of a shared sequence with INCR, and the reply carries it.
- Macros
- Manual
/// Numbers each order with `INCR`, whose answer the reply carries.
#[subscriber(RedisStream::new("orders").group("numbering"), reply)]
async fn assign_number(
order: &Order,
Ctx(pool): Ctx<keys::FredPool>,
) -> Result<Numbered, HandlerOutcome> {
match pool.incr::<i64, _>("orders:sequence").await {
Ok(number) => Ok(Numbered {
order_id: order.id,
number,
}),
Err(err) => {
tracing::warn!(order.id, %err, "the sequence is out of reach");
Err(HandlerOutcome::retry())
}
}
}
/// Numbers each order with `INCR`, whose answer the reply carries.
struct AssignNumber;
impl Handle<Order, Numbered, (), PoolContext> for AssignNumber {
async fn handle(
&self,
order: &Order,
_outs: &(),
ctx: &mut Context<'_, PoolContext>,
) -> Result<Numbered, HandlerOutcome> {
let pool = ctx.context(keys::FredPool);
match pool.incr::<i64, _>("orders:sequence").await {
Ok(number) => Ok(Numbered {
order_id: order.id,
number,
}),
Err(err) => {
tracing::warn!(order.id, %err, "the sequence is out of reach");
Err(HandlerOutcome::retry())
}
}
}
}