跳到主要内容
本页尚未翻译

下面显示的是英文原文。

Publish

Publish is each form's one policy and its default: replies, slots and lifecycle hooks publish through it with no per-message setting.

Each form's prelude names its own policy Publish: FilePublish on a stream file, StdioPublish on a pipe. A service that uses both brokers globs the crate's prelude and writes the two names in full. The policy holds no connection; the runtime pairs it with the connected broker at startup. A registration that names no policy for its reply publishes through Publish, so the bare reply clause needs nothing at the mount site. .out(Ledger, Publish) wires an Out slot, and after_startup(Publish, ..) hands a lifecycle hook a publisher. A reply goes to the stream key its type declares with #[outgoing(name = "receipts")]. A reply type that declares no key is published where the subscriber says, with reply("receipts"). A publish carries a stream key and a payload, and its headers ride inside the payload in an envelope. The policy has no per-message setting, so the publish builder gains no step from this crate and a handler body keeps the plain bound Out<impl Publisher, Marker>. Each publish is written on its own: two publishes of one handler are two separate writes.

Example​

The service answers each order with a receipt and writes an audit line through the ledger slot.

/// The answer to an order, appended under the key the type declares.
#[derive(Debug, PartialEq, Deserialize, Serialize, Outgoing)]
#[outgoing(name = "receipts")]
struct Receipt {
order: u64,
}

/// The audit line of an order, on a key of its own.
#[derive(Debug, PartialEq, Deserialize, Serialize, Outgoing)]
#[outgoing(name = "audit")]
struct Audited {
order: u64,
}

#[derive(OutSlot)]
#[publishes(Audited)]
struct Ledger;

/// Answers each order with a receipt and writes its audit line through the ledger slot.
#[subscriber(FileStream::new("orders"), reply)]
async fn confirm(
order: &Order,
Out(ledger): Out<impl Publisher, Ledger>,
) -> Result<Receipt, HandlerOutcome> {
if let Err(error) = ledger.message(&Audited { order: order.id }).publish().await {
tracing::warn!(order.id, %error, "the audit line was not written");
return Err(HandlerOutcome::retry());
}
Ok(Receipt { order: order.id })
}

#[ruststream::app]
fn app() -> impl App {
RustStream::new(AppInfo::new("checkout", "0.1.0")).with_broker(
FileBroker::new("/var/lib/shop/orders.ss"),
|b| {
// The reply needs no policy: the runtime pairs the form's own `Publish`.
b.include(confirm).out(Ledger, Publish).build();
},
)
}