March Docs

SessionNode

SessionNode: the Session.Ops network transport. A protocol's @[endpoints] roles on two nodes talk over one peer connection (distributed actors, step 4 of specs/progress/2026-09-15-remote-actor-dispatch.md).

The transport is protocol-independent: Session.Ops speaks in endpoint ids (Int) and encoded messages (Bytes, the generated <P>_Msg.encode), so nothing here names a protocol's constructors and nothing needs generating. What a node writes:

let link = SessionNode.open(conn, "node-a", false, fn ep -> ...)   -- after connect_split / accept_split
let s = Session.attach(io, SessionNode.ops(link))
let st = Stream_Prod.register(s, 0)
... drive the role to its first suspension ...
SessionNode.serve(link)        -- deliveries, until the peer's endpoint closes
SessionNode.finish(link)

On the wire, per peer connection (the control/data split): data ACTOR_MSG "SessionNode.Deliver" [to, from, msg], through a NodeQueue (credit-based flow control); "SessionNode.Bye" when an endpoint closes. control "SessionNode.Hello" (the endpoint actor's GlobalPid; the ACCEPTING side announces first), CREDIT, and a final Bye.

Receiving: a delivery is sent to this node's endpoint actor, whose turn runs the continuation suspend installed. One actor, so one node's resumptions (and prints) run in mailbox order, which is the protocol's. "Consumed" for credit is "in the mailbox".

Types

Functions

fnfinishfinish(link : Link) : Unit#

Tear the link down: close data, say Bye on control, await the control reader, close control.

fnfirefire(handlers : Vault(Int -> Bytes -> Int -> Int), ep : Int, from : Int, msg : Bytes) : Int#
fnopenopen(conn : Peer, node_id : String, accepted : Bool, on_close : Int -> Unit) : Link#

Open the transport on a split peer connection (ClusterConn.connect_split / accept_split). Spawns this node's endpoint actor, exchanges endpoint pids on the control connection (the accepting side, [accepted] = true, announces first), starts the data connection's NodeQueue and the control reader. [on_close] runs when a local endpoint closes, with its endpoint id.

fnopsops(link : Link) : Session.Ops#

The Session.Ops for [link]: hand it to Session.attach.

fnserveserve(link : Link) : Unit#

Read deliveries on the data connection until the peer's endpoint closes. Every resumption runs in this node's endpoint actor, so call it after driving the local role to its first suspension.