Arcana::Bus
Central message router for agent-to-agent communication.
Supports direct delivery (send) and fan-out (publish/subscribe). Addresses are resolved through the directory when available — bare names like "memo" resolve to "memo:agent" or "memo:service" if unambiguous.
bus = Arcana::Bus.new writer = bus.mailbox("writer:agent") artist = bus.mailbox("artist:agent")
Direct message — bare name resolves if unambiguous
bus.send(Envelope.new(from: "writer:agent", to: "artist", ...))
Instance methods
Default max queue length for newly created mailboxes. nil means
unbounded (the historical default). Set via bin/arcana.cr from
ARCANA_MAILBOX_MAX_QUEUE. Mailboxes created with an explicit
max_queue: via a custom mailbox_factory override this.
Default max queue length for newly created mailboxes. nil means
unbounded (the historical default). Set via bin/arcana.cr from
ARCANA_MAILBOX_MAX_QUEUE. Mailboxes created with an explicit
max_queue: via a custom mailbox_factory override this.
Dispatch based on the envelope's ordering field (auto-resolved). Returns {reply, resolved_ordering}. Reply is nil for async.
Like deliver, but silently drops if the target mailbox doesn't exist.
Optional event recorder. When set, material bus actions (sends, publishes, subscribe/unsubscribe, prune) emit events. Newly created mailboxes inherit this recorder via their persistence hooks.
Optional event recorder. When set, material bus actions (sends, publishes, subscribe/unsubscribe, prune) emit events. Newly created mailboxes inherit this recorder via their persistence hooks.
Pending message count for an address. Returns 0 if no mailbox.
Prune stale agent listings and inactive mailboxes.
- Agent listings with last_seen older than
listing_ttlare removed. - Mailboxes with last_activity older than
mailbox_ttlare removed. Services are never pruned (they are re-registered from code at startup). Returns {pruned_listings, pruned_mailboxes}.
Publish an envelope to all subscribers of a topic.
The envelope's to is set to each subscriber's address on delivery.
Send an envelope and wait for a reply. Creates a temporary reply mailbox, sets reply_to, and blocks until a response arrives or the timeout expires. The reply mailbox is cleaned up automatically.
Resolve ordering: syntactic — service addresses (colon) are sync, agent addresses (no colon) are async.
Send an envelope to its to address. Raises if no mailbox exists,
or MailboxFull if the recipient's queue is at capacity.
Send, but return false instead of raising when the target mailbox
doesn't exist OR is full. Backpressure and missing-address both
collapse to "message didn't land" — callers who want to distinguish
should use send and catch specific errors.
Send an envelope and register an expectation for a reply on the sender's mailbox. Returns the correlation_id for tracking.
When true, every successful send fans out a metadata copy to the
sys.message.sent topic. Reactive infrastructure (like AIX's
tmux bridge) subscribes to it and gets push-quality wake
notifications without polling GET /events. Default OFF — enable
via ARCANA_SYSTEM_TOPICS=1 in the daemon, or set directly here.
Fanout cost: one extra Mailbox#deliver per subscriber per send.
When true, every successful send fans out a metadata copy to the
sys.message.sent topic. Reactive infrastructure (like AIX's
tmux bridge) subscribes to it and gets push-quality wake
notifications without polling GET /events. Default OFF — enable
via ARCANA_SYSTEM_TOPICS=1 in the daemon, or set directly here.
Fanout cost: one extra Mailbox#deliver per subscriber per send.