You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
BroadcastChannel doesn't fill in useful MessageEvent fields like source, or ports #59053
Please populate the Worker value in BroadcastChannel MessageEvents 'source' field the same way it is in WebWorkers.
There is currently no mechanism to compose Workers in the NodeJS APIs and this change would provide a mechanism to
solve that problem, if not for the general case, at least with only a small amount of additional bookkeeping on the part of
application developers.
Without a composition mechanism, it is extremely difficult to implement cross-cutting concerns between workers, and between workers and large subsystems in the main application. Which is problematic for many areas of production code including caching, telemetry, reloadable configuration, and security.
Fundamentally, there is no mechanism to tell if a Worker has terminated. And since Workers tend to be used for tasks with high utilization of the event toop, even sending a message to ask if anyone is still listening to the BroadcastChannel is not guaranteed to work on any reasonable time frame, and in particular for cross-cutting concerns who can't know what, for instance, the cutoff time is for image processing in the Image Worker, and that the Cache Worker has a cutoff of 1/100th of that time. Which then leads to a scenario where you've decided a Worker is dead and then the same worker pops back up 10 seconds later. What you need is worker.on('exit') which is unambiguous.
Version
All versions
Platform
All Platforms
Subsystem
node:worker_threads
What steps will reproduce the bug?
const util = require('util');
const channel = new BroadcastChannel('example');
if (isMainThread) {
channel.addEventListener('message', evt => {
console.log(util.inspect(evt)); // breakpoint here
});
} else {
channel.postMessage('hello');
}
@jdmarshall Please have a look at the proposed changes in this PR. I have updated the source field of Broadcast Channel events to reflect worker thread ids
@SudhansuBandha my project is concerned about the potential to not detect worker termination without having access to the worker object expected in the MessageEvent. ThreadId isn't going to support the full lifecycle needed for robust use of this communication channel.
Will it be feasible for Broadcast Channel to share sender's worker object to acess full lifecycle of worker considering that workers run on different isolates? Maybe creating an extension in Broadcast Channel address this since event.source is null. @jasnell would love to have your feeback on this before making any changes.
I'm going to change the summary for this story a bit because the ask I'm making has much bigger implications than I think I have communicated. There's a giant hole in the middle of the Worker API specification and I believe this change fills in most of that hole, while lesser solutions do essentially nothing to fill it in. Which is why I'm being particular about how I'd like it to be fixed.
MessageEvent.source should remain unchanged, since for BroadcastChannel it is expected to be null under the web platform semantics.
Exposing the actual Worker object through source could also unintentionally expose APIs such as terminate(), ref(), and unref(), which should not necessarily be available to another Worker.
For Worker-to-Worker communication, postMessageToThread() already provides communication between threads based on the existing MessagePort infrastructure that can be used for direct inter-worker communication.
I think creating an extension for events of BroadcastChannel originating Worker to providing reliable lifecycle information might be helpful to address this issue
@jdmarshall PTAL at this PR. I have created this setup to emit events which get triggered when worker exits in a Broadcast Channel. I know this might not solve all the lifecycle events tracking but hopefully this can be a good start based on which we can make further progress.
One problem with populating source is that it exposes native worker apis like terminate(), ref(), and unref() to other threads which can lead to termination of source worker by another worker. That is something which should not be allowed.
I don't know if I agree with that. We are all running in the same sandbox, employed by the same bosses. The security guarantee is if you do something egregious you lose your job, not a VM enforcing security constraints.
I can always just call process.exit(0) in main and kill the entire VM.
Activity
SudhansuBandha commentedon Jul 7, 2026
@jdmarshall Please have a look at the proposed changes in this PR. I have updated the source field of Broadcast Channel events to reflect worker thread ids
jdmarshall commentedon Jul 7, 2026
But the spec has a Worker object in the source field, not the threadId.
worker: populate BroadcastChannel MessageEvent source
jdmarshall commentedon Aug 11, 2026
@SudhansuBandha my project is concerned about the potential to not detect worker termination without having access to the worker object expected in the MessageEvent. ThreadId isn't going to support the full lifecycle needed for robust use of this communication channel.
SudhansuBandha commentedon Aug 12, 2026
Will it be feasible for Broadcast Channel to share sender's worker object to acess full lifecycle of worker considering that workers run on different isolates? Maybe creating an extension in Broadcast Channel address this since
event.sourceis null.@jasnell would love to have your feeback on this before making any changes.
jdmarshall commentedon Aug 12, 2026
I suppose that's a question of how much of the logic for WebWorkers is within V8 and how much of it is tacked on by chrome.
jdmarshall commentedon Aug 12, 2026
I'm going to change the summary for this story a bit because the ask I'm making has much bigger implications than I think I have communicated. There's a giant hole in the middle of the Worker API specification and I believe this change fills in most of that hole, while lesser solutions do essentially nothing to fill it in. Which is why I'm being particular about how I'd like it to be fixed.
SudhansuBandha commentedon Aug 20, 2026
MessageEvent.sourceshould remain unchanged, since forBroadcastChannelit is expected to be null under the web platform semantics.Exposing the actual Worker object through source could also unintentionally expose APIs such as
terminate(),ref(), andunref(), which should not necessarily be available to another Worker.For Worker-to-Worker communication,
postMessageToThread() already provides communication between threads based on the existingMessagePortinfrastructure that can be used for direct inter-worker communication.I think creating an extension for events of
BroadcastChanneloriginating Worker to providing reliable lifecycle information might be helpful to address this issueworker: emit worker exit notifications on BroadcastChannel
worker: emit worker exit notifications on BroadcastChannel
worker: emit worker exit notifications on BroadcastChannel
SudhansuBandha commentedon Aug 27, 2026
@jdmarshall PTAL at this PR. I have created this setup to emit events which get triggered when worker exits in a Broadcast Channel. I know this might not solve all the lifecycle events tracking but hopefully this can be a good start based on which we can make further progress.
jdmarshall commentedon Aug 27, 2026
That would help but I’m still curious why it’s difficult to emulate the browser API? Node isnt doing what Chrome already has.
SudhansuBandha commentedon Aug 27, 2026
One problem with populating source is that it exposes native worker apis like
terminate(),ref(), andunref()to other threads which can lead to termination of source worker by another worker. That is something which should not be allowed.jdmarshall commentedon Aug 27, 2026
I don't know if I agree with that. We are all running in the same sandbox, employed by the same bosses. The security guarantee is if you do something egregious you lose your job, not a VM enforcing security constraints.
I can always just call
process.exit(0)in main and kill the entire VM.worker: emit worker exit notifications on BroadcastChannel
worker: emit worker exit notifications on BroadcastChannel
worker: emit worker exit notifications on BroadcastChannel
worker: emit worker exit notifications on BroadcastChannel
worker: emit worker exit notifications on BroadcastChannel
worker: emit worker exit notifications on BroadcastChannel
worker: emit worker exit notifications on BroadcastChannel