cluster: fix edge cases that throw ERR_INTERNAL_ASSERTION
Some cases use both cluster
and net
/cluser
will throw
ERR_INTERNAL_ASSERTION when listen
/bind
to the port of 0
, like below:
const cluster = require('cluster')
const dgram = require('dgram')
const kPort = 0;
function child() {
for (let i = 0; i < 2; i += 1) {
const socket = new dgram.Socket('udp4')
socket.bind(kPort)
setTimeout(() => {
socket.close()
const socket2 = new dgram.Socket('udp4')
socket2.bind(kPort);
}, 100)
}
}
if (cluster.isMaster) {
cluster.fork(__filename)
} else {
child()
}
would throw:
internal/assert.js:14
throw new ERR_INTERNAL_ASSERTION(message);
^
Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js or incorrect usage of Node.js internals.
Please open an issue with this stack trace at https://github.com/nodejs/node/issues
at assert (internal/assert.js:14:11)
at SharedHandle.add (internal/cluster/shared_handle.js:28:3)
at queryServer (internal/cluster/master.js:309:10)
at Worker.onmessage (internal/cluster/master.js:249:5)
at ChildProcess.onInternalMessage (internal/cluster/utils.js:47:8)
at ChildProcess.emit (events.js:326:22)
at emit (internal/child_process.js:906:12)
at processTicksAndRejections (internal/process/task_queues.js:81:21) {
code: 'ERR_INTERNAL_ASSERTION'
}
After some investigation, I believe it's because we remove the indexesKey
when close
servers while it might reference more than one index
:
This PR maitains a separate map of the index to fix the issue.
Checklist
-
make -j4 test
(UNIX), orvcbuild test
(Windows) passes -
tests and/or benchmarks are included -
commit message follows commit guidelines