cluster: ignore queryServer msgs on disconnection
It avoids the creation of unnecessary handles. This issue is causing intermitent failures in `test-cluster-disconnect-race` on `FreeBSD` and `OS X`. The problem is that the `worker2.disconnect` is being called on the master before the `queryServer` is handled, causing the worker to be deleted, then the Server handle is created afterwards. Later on, when `removeWorker` is called from the `exit` handler, there are no workers left, but one handle, thus the `AssertionError`. Add a new `test/sequential/test-cluster-disconnect-leak` based on `test-cluster-disconnect-race` that creates lots of workers and fails consistently without this patch. PR-URL: https://github.com/nodejs/node/pull/4465 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Johan Bergström <bugs@bergstroem.nu> Reviewed-By: Rich Trott <rtrott@gmail.com>
This commit is contained in:
parent
b46c627ee9
commit
f9f1dd9290
@ -446,6 +446,9 @@ function masterInit() {
|
||||
}
|
||||
|
||||
function queryServer(worker, message) {
|
||||
// Stop processing if worker already disconnecting
|
||||
if (worker.suicide)
|
||||
return;
|
||||
var args = [message.address,
|
||||
message.port,
|
||||
message.addressType,
|
||||
|
47
test/sequential/test-cluster-disconnect-leak.js
Normal file
47
test/sequential/test-cluster-disconnect-leak.js
Normal file
@ -0,0 +1,47 @@
|
||||
'use strict';
|
||||
// Flags: --expose-internals
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const net = require('net');
|
||||
const cluster = require('cluster');
|
||||
const handles = require('internal/cluster').handles;
|
||||
const os = require('os');
|
||||
|
||||
if (common.isWindows) {
|
||||
console.log('1..0 # Skipped: This test does not apply to Windows.');
|
||||
return;
|
||||
}
|
||||
|
||||
cluster.schedulingPolicy = cluster.SCHED_NONE;
|
||||
|
||||
if (cluster.isMaster) {
|
||||
const cpus = os.cpus().length;
|
||||
const tries = cpus > 8 ? 128 : cpus * 16;
|
||||
|
||||
const worker1 = cluster.fork();
|
||||
worker1.on('message', common.mustCall(() => {
|
||||
worker1.disconnect();
|
||||
for (let i = 0; i < tries; ++ i) {
|
||||
const w = cluster.fork();
|
||||
w.on('online', common.mustCall(w.disconnect));
|
||||
}
|
||||
}));
|
||||
|
||||
cluster.on('exit', common.mustCall((worker, code) => {
|
||||
assert.strictEqual(code, 0, 'worker exited with error');
|
||||
}, tries + 1));
|
||||
|
||||
process.on('exit', () => {
|
||||
assert.deepEqual(Object.keys(cluster.workers), []);
|
||||
assert.strictEqual(Object.keys(handles).length, 0);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var server = net.createServer();
|
||||
|
||||
server.listen(common.PORT, function() {
|
||||
process.send('listening');
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user