Skip to content

Add MessageChannel, receiveMessageOnPort and MessagePort transfer - #1108

Open
ctate wants to merge 8 commits into
mainfrom
ctate/add-messagechannel-receivemessageonport-5d9f36
Open

ctate wants to merge 8 commits into
mainfrom
ctate/add-messagechannel-receivemessageonport-5d9f36

Conversation

@ctate

@ctate ctate commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator
  • new MessageChannel() and receiveMessageOnPort from node:worker_threads, with ports that work in one thread or move to workers through postMessage's and workerData's transfer lists (Node's DataCloneError for an unlisted port).
  • Port messages and 'close' events follow Node's loop phases: batches before setImmediate, a port's own close after the poll phase, the other port's close after its queued messages.
  • Corpus 5793-5797 match Node v24.22.0, plain and with SCRIPTC_SAN=1.

new MessageChannel() from node:worker_threads makes two entangled
MessagePorts. They share the handle model of parentPort: postMessage
with the existing message clone, 'message' and 'close' events,
on/once, start, close, ref, unref and hasRef. A port's 'close' reaches
the other port after its queued messages. receiveMessageOnPort(port)
answers the next queued message as { message }, or undefined.

A channel is a thread-neutral record (scr_mailbox.c): each end has its
queue and the inbox of the thread that owns its port. A port listed in a
transfer list, given as postMessage's array or { transfer }, or as the
Worker constructor's transferList, travels with the message, and the
decoding thread adopts it. The sending port becomes unusable. A port in a
message without that listing throws DataCloneError, and so does a port
listing itself.

Port events follow Node's loop phases. Each port's queued messages
arrive as one batch, ports in creation order, before setImmediate
callbacks, with nextTicks and microtasks after each message (a new loop
hook keeps the pass going until the batch is delivered). A port's own
'close' runs in the following close phase, the latest close() first. The
other port's 'close' arrives on a later poll, in the order the notices
were sent, and only while the loop keeps running.
@vercel

vercel Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
scriptc Ready Ready Preview, v0 Oct 17, 2026 1:38pm UTC

This branch was successfully deployed

1 active deployment
Preview — 3fadf25b Deployed Oct 17, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant