From a5c27091cc4db6b2d9cc49de3ef9ed06dddcd5f2 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Sat, 29 Sep 2018 12:22:15 -0400 Subject: [PATCH 1/2] doc: specify cluster worker.kill() caveat worker.kill() relies on a graceful disconnect, which might not always be possible. This commit calls this out in the docs, and specifies worker.process.kill() as a non-graceful alternative. PR-URL: https://github.com/nodejs/node/pull/23165 Fixes: https://github.com/nodejs/node/issues/22703 Reviewed-By: Luigi Pinca Reviewed-By: Sakthipriyan Vairamani --- doc/api/cluster.md | 5 +++++ 1 file changed, 5 insertions(+) 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. From 1f7b6a6cc916a8bab942e579ed930e9e2d66c4e0 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Wed, 3 Oct 2018 20:58:40 -0400 Subject: [PATCH 2/2] test: terminate cluster worker in infinite loop Verify that worker.process.kill() can terminate a cluster worker stuck in an infinite loop. PR-URL: https://github.com/nodejs/node/pull/23165 Fixes: https://github.com/nodejs/node/issues/22703 Reviewed-By: Luigi Pinca Reviewed-By: Sakthipriyan Vairamani --- .../test-cluster-kill-infinite-loop.js | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 test/parallel/test-cluster-kill-infinite-loop.js 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) {} +}