From 7e11943259e2309f73db5ae58464113ce5a42bbf Mon Sep 17 00:00:00 2001 From: Ouyang Yadong Date: Thu, 7 Jul 2022 13:58:52 +0800 Subject: [PATCH] dgram: fix closing dgram sockets in cluster workers throws errors This fixes closing dgram sockets right after binding in cluster workers will throws `ERR_SOCKET_DGRAM_NOT_RUNNING` errors. --- lib/internal/cluster/child.js | 4 ++ .../test-dgram-cluster-close-in-listening.js | 38 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 test/parallel/test-dgram-cluster-close-in-listening.js diff --git a/lib/internal/cluster/child.js b/lib/internal/cluster/child.js index 00638e7784550b..8ae7058bc14280 100644 --- a/lib/internal/cluster/child.js +++ b/lib/internal/cluster/child.js @@ -111,6 +111,10 @@ cluster._getServer = function(obj, options, cb) { }); obj.once('listening', () => { + // short-lived sockets might have been closed + if (!indexes.has(indexesKey)) { + return; + } cluster.worker.state = 'listening'; const address = obj.address(); message.act = 'listening'; diff --git a/test/parallel/test-dgram-cluster-close-in-listening.js b/test/parallel/test-dgram-cluster-close-in-listening.js new file mode 100644 index 00000000000000..a88db2e8aaea71 --- /dev/null +++ b/test/parallel/test-dgram-cluster-close-in-listening.js @@ -0,0 +1,38 @@ +'use strict'; +// Ensure that closing dgram sockets in 'listening' callbacks of cluster workers +// won't throw errors. + +const common = require('../common'); +const dgram = require('dgram'); +const cluster = require('cluster'); + +if (cluster.isPrimary) { + for (let i = 0; i < 3; i += 1) { + cluster.fork(); + } +} else { + const buf = Buffer.alloc(1024, 42); + const socket = dgram.createSocket('udp4'); + + socket.on('error', common.mustNotCall()); + + socket.on('listening', common.mustCall(() => { + socket.close(); + })); + + socket.on('close', common.mustCall(() => { + cluster.worker.disconnect(); + })); + + // Get a random port for send + const portGetter = dgram.createSocket('udp4') + .bind(0, 'localhost', common.mustCall(() => { + // Adds a listener to 'listening' to send the data when + // the socket is available + socket.send(buf, 0, buf.length, + portGetter.address().port, + portGetter.address().address); + + portGetter.close(); + })); +}