iii-pubsub
v0.13.0-next.1Topic-based publish/subscribe messaging for real-time event distribution.
skill doc
React to topic publishes
how-toWhen to use
Register a subscribe trigger when a function should run automatically every time publish broadcasts to a configured topic. The handler receives the raw data value from the publish call — no envelope. Multiple triggers can subscribe to the same topic; each receives an independent copy of every event.
Reach for it when:
- A domain event from one part of the system should kick off side effects elsewhere — and the publisher shouldn't have to know about the consumers.
- You want loose coupling between an event source and its handlers (audit logs, mirror writes, real-time notifications).
- You're bridging cross-instance fan-out (configure the worker's
redisadapter so events propagate across an engine fleet).
Use a state or stream reactive trigger instead when the source of truth is a key/value store change rather than a discrete event. Use the iii-queue worker's durable:subscriber trigger when subscribers must process every event reliably (with retries and dead-letter handling); subscribe is fire-and-forget — a subscriber that's offline misses events.
Prerequisite: the iii-pubsub worker must be enabled in config.yaml. Handlers and triggers are registered from a connected worker via iii.registerFunction and iii.registerTrigger.
Inputs
Registration is the standard two-step pattern: define the handler, then bind it to the subscribe trigger.
Handler function
Register any function id. The handler receives the raw data value passed to the matching publish call — no envelope, no metadata, just the payload.
// iii.registerFunction — handler id only; no engine payload.
{ "id": "notifications::on-order-shipped" }Trigger registration
{
"type": "subscribe", // required. Must be exactly "subscribe".
"function_id": "notifications::on-order-shipped", // required. Handler invoked when a publish matches the topic.
"config": {
"topic": "orders.shipped" // required (non-empty). The trigger only fires for publishes to this exact topic — no wildcards.
}
}type, function_id, and config.topic are required. topic must be non-empty — registering with an empty topic logs a warning and the trigger never fires (per engine/src/workers/pubsub/pubsub.rs:101-105). Topic matching is exact string equality; the worker does not interpret hierarchical patterns or wildcards.
To subscribe to multiple topics, register one trigger per topic. Multiple triggers on the same topic each fire independently — the broadcast is true fan-out.
Outputs
The handler receives the raw data value the publisher sent — whatever JSON shape that is, returned unchanged:
// Example: when the publisher sent `data: { "orderId": "abc-123", "status": "shipped" }`
{ "orderId": "abc-123", "status": "shipped" }There is no envelope, no topic field, no metadata. If the handler needs to know which topic the message arrived on (e.g., one handler bound to multiple topics), include the topic inside the published data itself.
The handler's return value is ignored. Errors from the handler are logged but do not affect the originating publish call site or other subscribers — each subscriber runs independently. There is no retry: a handler that fails skips the event entirely.
Worked example
Subscribe a handler to the orders.shipped topic so it fires on every matching publish:
{
"type": "subscribe",
"function_id": "notifications::on-order-shipped",
"config": { "topic": "orders.shipped" }
}The typical pattern is one trigger per (handler, topic) pair: a notifications handler subscribed to orders.shipped, an audit handler subscribed to users.deleted, etc. For multi-topic handlers, embed the topic in the data payload at publish time. For runnable scaffolds, see the pubsub worker source and SDK examples in the iii main repo.
Related
publish— the broadcast side. Every event delivered to this trigger comes from apublishcall.iii-pubsubadapter —adapter.name: local(default; in-process broadcast channels) only delivers to subscribers on this engine instance. Switch toadapter.name: rediswithredis_urlfor cross-instance fan-out via Redis Pub/Sub.iii-queuetopic-based subscribers (durable:subscribertrigger) — for reliable delivery with retries and dead-letter support;subscribeis fire-and-forget.