Skip to content

Worker threads can trigger MaxListenersExceededWarning when stdout/stderr are overloaded or corked #37582

@loganfsmyth

Description

@loganfsmyth
  • Version: 15.10.0
  • Platform: macOS
  • Subsystem: worker

What steps will reproduce the bug?

Run node example.js with these files:

example.js

const { Worker } = require("worker_threads");

process.stdout.cork();
for (let i = 0; i < 15; i++) {
  new Worker("./example_worker.js");
}
process.stdout.write(Buffer.alloc(process.stdout.writableHighWaterMark, "!"));

example_worker.js

console.log("OUT");

How often does it reproduce? Is there a required condition?

Reproduces consistently.

What is the expected behavior?

Should run and then exit silently.

What do you see instead?

Runs and logs a warning:

(node:23883) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 drain listeners added to [WriteStream]. Use emitter.setMaxListeners() to increase limit
(Use `node --trace-warnings ...` to show where the warning was created)

Additional information

The worker logic uses .pipe() and tries to avoid issues like this with its pipeWithoutWarning helper, but that doesn't apply to events that are added internally within pipe at a later time, so that approach just doesn't seem right.

.pipe() adds dest.on("drain", ... when the destination is corked or overloaded, and so if the number of workers is > defaultMaxListeners and the destination write returns false, Node logs a warning.

Metadata

Metadata

Assignees

No one assigned

    Labels

    workerIssues and PRs related to Worker support.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions