diff --git a/doc/api/cluster.md b/doc/api/cluster.md index 54b470e0f0e3d5..868d52be88dfae 100644 --- a/doc/api/cluster.md +++ b/doc/api/cluster.md @@ -394,6 +394,11 @@ This function will kill the worker. In the master, it does this by disconnecting the `worker.process`, and once disconnected, killing with `signal`. In the worker, it does it by disconnecting the channel, and then exiting with code `0`. +Because `kill()` attempts to gracefully disconnect the worker process, it is +susceptible to waiting indefinitely for the disconnect to complete. For example, +if the worker enters an infinite loop, a graceful disconnect will never occur. +If the graceful disconnect behavior is not needed, use `worker.process.kill()`. + Causes `.exitedAfterDisconnect` to be set. This method is aliased as `worker.destroy()` for backwards compatibility. diff --git a/test/parallel/test-cluster-kill-infinite-loop.js b/test/parallel/test-cluster-kill-infinite-loop.js new file mode 100644 index 00000000000000..f53e6e3976ec28 --- /dev/null +++ b/test/parallel/test-cluster-kill-infinite-loop.js @@ -0,0 +1,21 @@ +'use strict'; +const common = require('../common'); +const cluster = require('cluster'); +const assert = require('assert'); + +if (cluster.isMaster) { + const worker = cluster.fork(); + + worker.on('online', common.mustCall(() => { + // Use worker.process.kill() instead of worker.kill() because the latter + // waits for a graceful disconnect, which will never happen. + worker.process.kill(); + })); + + worker.on('exit', common.mustCall((code, signal) => { + assert.strictEqual(code, null); + assert.strictEqual(signal, 'SIGTERM'); + })); +} else { + while (true) {} +}