Repository navigation
fix(node:worker_threads): MessageChannel ports + transfer/clone markers - #3808
Merged
Merged
Conversation
Implement same-process MessageChannel/MessagePort delivery and the
transfer/clone marker helpers.
- new MessageChannel() returns {port1, port2} backed by a same-process
paired-port registry. port.postMessage(v) JSON-serializes v and
enqueues it on the peer's inbox.
- receiveMessageOnPort(port) synchronously pops one queued message and
returns { message: value }, or undefined when empty.
- port.on('message', cb) / addListener / once register a listener; the
event-loop pump drains inboxes and invokes the callback. port.start()
enables delivery; port.close() fires 'close'.
- markAsUncloneable(obj) now records the object; postMessage of a marked
object throws a DataCloneError.
Closes #3157
Closes #3159
… real object
- new MessageChannel() via named import now lowers to the worker_threads
NativeMethodCall (like the namespace form), so the runtime allocates the
real { port1, port2 } object instead of an empty user-class object.
- chan.port1 / chan.port2 on a MessageChannel-typed value lower to a plain
object field read (returning the port object) rather than a zero-arg
native getter. parentPort stays on native-receiver dispatch.
- port.on('message', cb) registers the runtime event-loop pump so a
MessageChannel-only program ticks the loop and delivers queued messages.
…157-3159-3156 # Conflicts: # crates/perry-hir/src/lower/expr_new.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements same-process
MessageChannel/MessagePortdelivery and theworker_threads transfer/clone marker helpers.
Closes #3157
Closes #3159
Implementation
#3157 — MessageChannel ports + receiveMessageOnPort
new MessageChannel()now returns a real heap object{ port1, port2 }backed by a same-process paired-port registry (
MESSAGE_PORTSkeyed by amonotonic port id). Each port object carries closure-valued
postMessage/on/addListener/once/off/removeListener/close/start/ref/unref/hasRef, each capturing its port id.port.postMessage(v)JSON-serializesv(structured-clone-like valuesemantics, matching the existing parentPort stdin/stdout IPC path) and
enqueues it on the peer port's inbox.
receiveMessageOnPort(port)synchronously pops one queued message andreturns
{ message: value }, orundefinedwhen the inbox is empty.port.on('message', cb)registers a listener and starts the port; theevent-loop pump (
js_worker_threads_channels_process_pending) drainsinboxes and invokes listeners on the main thread.
port.close()queues acloseevent on the port. The pump's "has active handles" check keeps theloop alive while a started port has queued messages or a pending close.
worker_threads mutable root scanner.
#3159 — transfer / clone markers
markAsUncloneable(obj)now records the object;port.postMessageof amarked-uncloneable value throws a
DataCloneError.(
markAsUntransferable/isMarkedAsUntransferablewere alreadyimplemented.)
HIR lowering
new MessageChannel()via named import now routes to the samereceiver-less
worker_threadsNativeMethodCallas thenew worker_threads.MessageChannel()member form, so the runtime allocatesthe real
{ port1, port2 }object instead of an empty user-class object.chan.port1/chan.port2on aMessageChannel-typed value lower to aplain object field read (returning the port object) rather than a zero-arg
native getter. parentPort stays on its native-receiver dispatch path.
No new HIR variants added.
Validation
Gap test
test-files/test_gap_worker_channels_3157plus.ts(MessageChannelsync
receiveMessageOnPort, asyncon('message')delivery, port close, andthe marker helpers) is byte-identical to
node --experimental-strip-typesunder the default auto-optimize compile../scripts/check_file_size.sh,cargo fmt --all -- --check, andcargo test -p perry-hirare green.