cluster: send suicide message on disconnect
authorcjihrig <cjihrig@gmail.com>
Mon, 9 Nov 2015 20:08:50 +0000 (15:08 -0500)
committerJames M Snell <jasnell@gmail.com>
Wed, 23 Dec 2015 16:38:33 +0000 (08:38 -0800)
This commit causes Worker.prototype.disconnect() to send a
suicide message to the cluster master. The function is also
restructured to eliminate redundant code.

Fixes: https://github.com/nodejs/node/issues/3238
PR-URL: https://github.com/nodejs/node/pull/3720
Reviewed-By: James M Snell <jasnell@gmail.com>
lib/cluster.js
test/parallel/test-regress-GH-3238.js [new file with mode: 0644]

index eef8bd2..bbb6188 100644 (file)
@@ -651,26 +651,24 @@ function workerInit() {
 
   Worker.prototype.disconnect = function() {
     this.suicide = true;
-    var waitingHandles = 0;
+    let waitingCount = 1;
 
-    function checkRemainingHandles() {
-      waitingHandles--;
-      if (waitingHandles === 0) {
+    function checkWaitingCount() {
+      waitingCount--;
+      if (waitingCount === 0) {
+        send({ act: 'suicide' });
         process.disconnect();
       }
     }
 
-    for (var key in handles) {
-      var handle = handles[key];
+    for (const key in handles) {
+      const handle = handles[key];
       delete handles[key];
-      waitingHandles++;
-      handle.owner.close(checkRemainingHandles);
-    }
-
-    if (waitingHandles === 0) {
-      process.disconnect();
+      waitingCount++;
+      handle.owner.close(checkWaitingCount);
     }
 
+    checkWaitingCount();
   };
 
   Worker.prototype.destroy = function() {
diff --git a/test/parallel/test-regress-GH-3238.js b/test/parallel/test-regress-GH-3238.js
new file mode 100644 (file)
index 0000000..a92a09d
--- /dev/null
@@ -0,0 +1,21 @@
+'use strict';
+const common = require('../common');
+const assert = require('assert');
+const cluster = require('cluster');
+
+if (cluster.isMaster) {
+  const worker = cluster.fork();
+  let disconnected = false;
+
+  worker.on('disconnect', common.mustCall(function() {
+    assert.strictEqual(worker.suicide, true);
+    disconnected = true;
+  }));
+
+  worker.on('exit', common.mustCall(function() {
+    assert.strictEqual(worker.suicide, true);
+    assert.strictEqual(disconnected, true);
+  }));
+} else {
+  cluster.worker.disconnect();
+}