Перейти к основному содержимому
Эта страница ещё не переведена

Ниже показан английский оригинал.

RequestReply

RequestReply sends a request from a handler and awaits the correlated answer, on a broker that correlates replies natively.

NATS-style brokers correlate replies, and the memory broker does too; Kafka and classic queues do not offer this capability. A handler bounds its slot Out<impl RequestReply, Marker>, and the mount site binds the broker's request policy, which its prelude names Request. request(message, timeout) publishes the message and resolves on the first answer, or fails once the time runs out. The request is an OutgoingMessage of bytes the handler encoded, and the answer is the broker's incoming message, which the handler decodes. The request goes to the broker directly, past the slot's transforms and the app's publish layers. The broker names an inbox for the answer: the memory broker puts it in the reply-to header. The responder is an ordinary reply handler whose reply goes to that inbox, through a naming transform. The slot also publishes with the builder, what its #[publishes(..)] list admits.

Example​

The handler asks the quote service for a price, then publishes the priced order through the same slot.

#[derive(OutSlot)]
#[publishes(Priced)]
struct Pricing;

#[subscriber("orders")]
async fn price(order: &Order, Out(pricing): Out<impl RequestReply, Pricing>) -> HandlerOutcome {
let Ok(ask) = serde_json::to_vec(&Ask { id: order.id }) else {
return HandlerOutcome::drop();
};
let request = OutgoingMessage::new("quotes.ask", ask.as_slice());
let Ok(answer) = pricing.request(request, Duration::from_secs(2)).await else {
return HandlerOutcome::retry();
};
let Ok(quote) = serde_json::from_slice::<Quote>(answer.payload()) else {
return HandlerOutcome::drop();
};
let priced = Priced {
id: order.id,
price: quote.price,
};
if pricing.message(&priced).publish().await.is_err() {
return HandlerOutcome::retry();
}
HandlerOutcome::ack()
}

The responder answers on the inbox the request named.

fn app() -> impl App {
RustStream::new(AppInfo::new("orders", "0.1.0")).with_broker(MemoryBroker::new(), |b| {
// The broker's request policy: its live publisher correlates replies.
b.include(price).out(Pricing, Request).build();
b.include(quote_price).out_reply(Publish).transform(ToInbox);
})
}