Cross-app calls
A run may send messages to other apps (env::xcall(app, method, &args)). The
message is a follow-up: it runs after the sending entry commits. The guest
API is in Cross-app calls; this page is how the
cluster runs them (crates/node/src/component/xcall.rs).
Outbox
Section titled “Outbox”A run’s messages go to its outcome. When the entry ends Ok, they are appended,
in order, to the source app’s outbox, kept as host rows in the source app’s
state. A failed run sends nothing.
Delivery
Section titled “Delivery”The source’s leader delivers the head of its outbox one message at a time, so
messages leave each source in order. The target runs the method as an xcall
delivery, with Caller::App(<source>).
Authorization
Section titled “Authorization”The node that runs the target checks:
- Entry point. The target method’s ABI must allow the source:
#[app::allow(app = "<source>")]orallow(app = "*")(allowApps). - Boundary. The two apps belong to the same organization, or, outside any organization, have the same owner.
- Provenance. The target sees the caller as
Caller::App(<source>), set by the node; no argument can claim it.
Synchronous calls and views (env::xcall_call, env::xcall_view) pass the same
checks and answer at once.
Deduplication
Section titled “Deduplication”The target keeps, per source app, the highest sequence number it applied; a message at or below it is answered as delivered without running. A leader change on either side never runs a message twice.
Retries and dead letters
Section titled “Retries and dead letters”A timeout or an unreachable target is retried with backoff for up to an hour
from the send. Then, or at once for a deleted target, one outside the
organization, or one that is not a component (an SDK 0.12 app the node no
longer runs), the message goes to the source’s dead letters (the newest 1,000),
and the source’s onXcallFailed runs if its ABI has one that allows the system.
Anything the target answered, an app error or a trap included, is a final
answer.
Limits
Section titled “Limits”A run may send at most 100 messages; an empty or overlong app id or method, or a
reserved (__) method, is refused at the send.