From 3c5354869e993ab645f85a2c73ce72f8af014de2 Mon Sep 17 00:00:00 2001 From: theanarkh Date: Sun, 28 Aug 2022 23:03:12 +0800 Subject: [PATCH] cluster: fix cluster rr distribute error PR-URL: https://github.com/nodejs/node/pull/44202 Reviewed-By: James M Snell --- lib/internal/cluster/round_robin_handle.js | 4 +++ test/parallel/test-cluster-accept-fail.js | 30 ++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 test/parallel/test-cluster-accept-fail.js diff --git a/lib/internal/cluster/round_robin_handle.js b/lib/internal/cluster/round_robin_handle.js index a881ca10bcb9de..29a87e716e8f21 100644 --- a/lib/internal/cluster/round_robin_handle.js +++ b/lib/internal/cluster/round_robin_handle.js @@ -98,6 +98,10 @@ RoundRobinHandle.prototype.remove = function(worker) { }; RoundRobinHandle.prototype.distribute = function(err, handle) { + // If `accept` fails just skip it (handle is undefined) + if (err) { + return; + } append(this.handles, handle); // eslint-disable-next-line node-core/no-array-destructuring const [ workerEntry ] = this.free; // this.free is a SafeMap diff --git a/test/parallel/test-cluster-accept-fail.js b/test/parallel/test-cluster-accept-fail.js new file mode 100644 index 00000000000000..29d57783a9d11f --- /dev/null +++ b/test/parallel/test-cluster-accept-fail.js @@ -0,0 +1,30 @@ +// Flags: --expose-internals +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); +const cluster = require('cluster'); +const rr = require('internal/cluster/round_robin_handle'); + +if (cluster.isPrimary) { + const distribute = rr.prototype.distribute; + rr.prototype.distribute = function(err, handle) { + assert.strictEqual(err, 0); + handle.close(); + distribute.call(this, -1, undefined); + }; + cluster.schedulingPolicy = cluster.SCHED_RR; + cluster.fork(); +} else { + const server = net.createServer(common.mustNotCall()); + server.listen(0, common.mustCall(() => { + + const socket = net.connect(server.address().port); + + socket.on('close', common.mustCall(() => { + server.close(common.mustCall(() => { + process.disconnect(); + })); + })); + })); +}