diff --git a/lib/cluster.js b/lib/cluster.js index ca1005b738068f..bb4b60a2fc489e 100644 --- a/lib/cluster.js +++ b/lib/cluster.js @@ -627,12 +627,26 @@ function workerInit() { Worker.prototype.disconnect = function() { this.suicide = true; + var waitingHandles = 0; + + function checkRemainingHandles() { + waitingHandles--; + if (waitingHandles === 0) { + process.disconnect(); + } + } + for (var key in handles) { var handle = handles[key]; delete handles[key]; - handle.close(); + waitingHandles++; + handle.owner.close(checkRemainingHandles); } - process.disconnect(); + + if (waitingHandles === 0) { + process.disconnect(); + } + }; Worker.prototype.destroy = function() { diff --git a/test/parallel/test-cluster-worker-wait-server-close.js b/test/parallel/test-cluster-worker-wait-server-close.js new file mode 100644 index 00000000000000..0f1836c7eccaa2 --- /dev/null +++ b/test/parallel/test-cluster-worker-wait-server-close.js @@ -0,0 +1,42 @@ +'use strict'; + +var common = require('../common'); +var assert = require('assert'); +var cluster = require('cluster'); +var net = require('net'); + +if (cluster.isWorker) { + net.createServer(function(socket) { + // Wait for any data, then close connection + socket.on('data', socket.end.bind(socket)); + }).listen(common.PORT, common.localhostIPv4); +} else if (cluster.isMaster) { + + var connectionDone; + var ok; + + // start worker + var worker = cluster.fork(); + + // Disconnect worker when it is ready + worker.once('listening', function() { + net.createConnection(common.PORT, common.localhostIPv4, function() { + var socket = this; + worker.disconnect(); + setTimeout(function() { + socket.write('.'); + connectionDone = true; + }, 1000); + }); + }); + + // Check worker events and properties + worker.once('disconnect', function() { + assert.ok(connectionDone, 'disconnect should occur after socket close'); + ok = true; + }); + + process.once('exit', function() { + assert.ok(ok); + }); +}