node.jseventsnode-worker-threads

How to increase `MaxListeners` on a EventTarget/BroadcastChannel?


I play a bit with worker threads and need to pass some data between them. In my code i register for each component a new event listener, which results in a

(node:47363) MaxListenersExceededWarning: Possible EventTarget memory leak detected. 11 message listeners added to [MessagePort [EventTarget]]. MaxListeners is 10. Use events.setMaxListeners() to increase limit
    at [kNewListener] (node:internal/event_target:562:17)
    at MessagePort.<anonymous> (node:internal/worker/io:225:12)
    at MessagePort.addEventListener (node:internal/event_target:686:23)
    at MessagePort.on (node:internal/event_target:965:10)
    at new Command (/home/marc/projects/OpenHaus/backend/components/endpoints/class.command.js:148:24)
    at /home/marc/projects/OpenHaus/backend/components/endpoints/class.endpoint.js:90:20
    at Array.map (<anonymous>)
    at new Endpoint (/home/marc/projects/OpenHaus/backend/components/endpoints/class.endpoint.js:89:38)
    at /home/marc/projects/OpenHaus/backend/components/endpoints/index.js:133:24
    at Array.forEach (<anonymous>)

Error, because i have 12 components. I wonder how i can increase the MaxListeners, on the BroadcastChannel, exists no method setMaxListeners():

const channel = new BroadcastChannel("events");
channel.setMaxListeners(100);
/home/marc/projects/OpenHaus/backend/system/component/class.events.js:6
channel.setMaxListeners(100);
        ^

TypeError: channel.setMaxListeners is not a function
    at Object.<anonymous> (/home/marc/projects/OpenHaus/backend/system/component/class.events.js:6:9)
    at Module._compile (node:internal/modules/cjs/loader:1730:14)
    at Object..js (node:internal/modules/cjs/loader:1895:10)
    at Module.load (node:internal/modules/cjs/loader:1465:32)
    at Function._load (node:internal/modules/cjs/loader:1282:12)
    at TracingChannel.traceSync (node:diagnostics_channel:322:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:235:24)
    at Module.require (node:internal/modules/cjs/loader:1487:12)
    at require (node:internal/modules/helpers:135:16)
    at Object.<anonymous> (/home/marc/projects/OpenHaus/backend/index.js:159:21)

Node.js v22.16.0

I want to increase the allow listeners only for this EventTarget, not global.


Solution

  • Reading the documentation about EventEmitter, i found the static method: setMaxListeners(), where you can pass a EventTarget/EventEmitter instance.

    const { setMaxListeners } = require("events");
    const { BroadcastChannel } = require("worker_threads");
    
    const channel = new BroadcastChannel("foo");
    
    // Error: "channel.setMaxListeners is not a function"
    //channel.setMaxListeners(15); // does not work, 
    
    // THIS FIXES THE WARNING!
    setMaxListeners(15, channel); // this works
    
    for (let i = 0; 12 >= i; i += 1) {
        channel.addEventListener("bar", ({ data }) => { console.log(data) })
    }