Skip to content

Commit d72886a

Browse files
committed
Signal handling: Don't exit if there are other signal listeners
1 parent 383f5aa commit d72886a

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

src/master/implementation.node.ts

+19-2
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,29 @@ interface Terminable {
3131
terminate(this: Terminable): any
3232
}
3333

34-
// Terminates the workers, empties the workers array, and exits.
34+
// Terminates the workers, empties the workers array, and possibly exits.
3535
const onSignal = (workers: Terminable[], signal: string) => {
3636
// worker.terminate() might return a Promise or might be synchronous. This async helper function
3737
// creates a consistent interface.
3838
const terminate = async (worker: Terminable) => worker.terminate()
39-
Promise.all(workers.map(worker => terminate(worker).catch(() => {}))).then(() => process.exit(1))
39+
Promise.all(workers.map(worker => terminate(worker).catch(() => {}))).then(() => {
40+
// Adding a signal listener suppresses the default signal handling behavior. That default
41+
// behavior must be replicated here, but only if the default behavior isn't intentionally
42+
// suppressed by another signal listener. Unfortunately there is no robust way to determine
43+
// whether the default behavior was intentionally suppressed, so a heuristic is used. (Note: The
44+
// 'exit' event is not suitable for terminating workers because it is not emitted when the
45+
// default signal handler terminates the process.)
46+
if (process.listenerCount(signal) > 1) {
47+
// Assume that one of the other signal listeners will take care of calling process.exit().
48+
// This assumption breaks down if all of the other listeners are making the same assumption.
49+
return
50+
}
51+
// Right now this is the only signal listener, so assume that this listener is to blame for
52+
// inhibiting the default signal handler. (This assumption fails if the number of listeners
53+
// changes during signal handling. This can happen if a listener was added by process.once().)
54+
// Mimic the default behavior, which is to exit with a non-0 code.
55+
process.exit(1)
56+
})
4057
workers.length = 0
4158
}
4259

0 commit comments

Comments
 (0)