RemoteCall
RemoteCall: the L4 remote-procedure-call safety core (P1 L4).
A remote function reference is {module, name, sig_hash, impl_hash}, stamped at compile time for a function the author has enrolled as a remote target. Node.call frames {fref, msgpack(args), reply_to, deadline} over the net-kernel; the remote runs a CAS admission check before invoking:
- sig_hash mismatch -> Reject(TypeMismatch) — incompatible signature, a
hard type error; never invoke.
* impl_hash mismatch -> Reject(VersionSkew) — same type, different body;
the peer could (P6) ship the matching body, otherwise reject.
* both match -> Accept — invoke the local native copy.Failure isolation: deadline expiry, netsplit, or a remote crash come back as a CallError (DeadlineExceeded / NoConnection / RemoteExit), never a hang.
This module is the pure core: the reference, the wire protocol (MessagePack codecs for request/reply, framable inside a NetFrame), the error taxonomy, and the admission decision. The enroll/stub/registry runtime mechanism (the actual function-by-identity dispatch) and the socket transport are separate layers.
Types
A compile-time-stamped reference to an enrolled remote target. sig_hash pins the (argument, return) TYPE; impl_hash pins the compiled body (a Merkle root over the call graph + type usage, from the CAS).
Why a remote call could not return its target's result. NoTarget = the peer has no function enrolled under this reference (wrong node / not enrolled). Forbidden = certificate mode (step 11b), and this node's or the peer's certificate lacks raw_send: RemoteCall is a raw primitive.
The CAS admission decision for an inbound call against the local target.
A call result: the MessagePack-encoded return value, or a failure.
A framed call. args is the MessagePack-encoded argument tuple; reply_to is the caller's global Pid; deadline is an absolute time (ms) after which the caller stops waiting; correlation matches a reply to its request.
Functions
Decode the bytes of encode_reply. Err for bytes that are not MessagePack or a value of the wrong shape (including an unknown error code).
Decode the bytes of encode_request. Err for bytes that are not MessagePack, a value of the wrong shape ("RemoteCall: malformed CallRequest" / "malformed RemoteRef"), or a reply-to pid GlobalPid cannot decode.
The MessagePack wire bytes of [rep]: [correlation, [0, Bin(payload)]] for a returned value, [correlation, [1, error]] for a failure, the error as [code] or [2, reason] for RemoteExit.
The MessagePack wire bytes of [req] (frame them with NetFrame.encode): [[module, fn, sig_hash, impl_hash], Bin(args), reply_to, deadline, correlation], reply_to in GlobalPid's encoding.
A failed reply to request [correlation]: Failed(e).
A one-line, human-readable description of [e], e.g. "deadline exceeded" or, for RemoteExit(reason), "remote process exited: <reason>".
A successful reply to request [correlation]: Returned(payload).
A reference to the remote target [module_name].[fn_name] with the given signature and implementation hashes.
A call request for [fref] with MessagePack-encoded [args], replying to [reply_to], giving up at [deadline] (absolute unix ms) and matched to its reply by [correlation].
CAS admission: does the inbound [fref] agree with the local target's hashes? Reject(TypeMismatch) when the sig_hash differs (checked first), Reject(VersionSkew) when only the impl_hash differs, else Accept. The names are not compared.
RemoteCall.verify("s1", "i1", RemoteCall.remote_ref("M", "f", "s1", "i2")) == Reject(VersionSkew)