Skip to content

Commit 588d179

Browse files
committed
net: track and close connections in a pre-exit hook
This is an attempt to fix the flaky failures on http(s) and tcp tests on Windows. Signed-off-by: James M Snell <jasnell@gmail.com> Assisted-by: Opencode/Opus 4.6
1 parent bdf75a6 commit 588d179

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

lib/net.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const {
3535
NumberParseInt,
3636
ObjectDefineProperty,
3737
ObjectSetPrototypeOf,
38+
SafeSet,
3839
Symbol,
3940
SymbolAsyncDispose,
4041
SymbolDispose,
@@ -912,6 +913,7 @@ Socket.prototype._destroy = function(exception, cb) {
912913
if (this._server) {
913914
debug('has server');
914915
this._server._connections--;
916+
this._server._connectionSockets?.delete(this);
915917
if (this._server._emitCloseIfDrained) {
916918
this._server._emitCloseIfDrained();
917919
}
@@ -1867,6 +1869,7 @@ function Server(options, connectionListener) {
18671869
}
18681870

18691871
this._connections = 0;
1872+
this._connectionSockets = new SafeSet();
18701873

18711874
this[async_id_symbol] = -1;
18721875
this._handle = null;
@@ -2365,6 +2368,7 @@ function onconnection(err, clientHandle) {
23652368
}
23662369

23672370
self._connections++;
2371+
self._connectionSockets.add(socket);
23682372
socket.server = self;
23692373
socket._server = self;
23702374
self.emit('connection', socket);
@@ -2436,6 +2440,22 @@ Server.prototype.close = function(cb) {
24362440
this._handle = null;
24372441
}
24382442

2443+
// Register a beforeExit handler to destroy any remaining connections
2444+
// before the process exits. This ensures connections are torn down
2445+
// during normal JS execution rather than during environment cleanup,
2446+
// where on Windows the IOCP completion processing can race with
2447+
// handle teardown.
2448+
if (this._connectionSockets.size > 0) {
2449+
const connections = this._connectionSockets;
2450+
const onBeforeExit = () => {
2451+
process.removeListener('beforeExit', onBeforeExit);
2452+
for (const socket of connections) {
2453+
socket.destroy();
2454+
}
2455+
};
2456+
process.on('beforeExit', onBeforeExit);
2457+
}
2458+
24392459
if (this._usingWorkers) {
24402460
let left = this._workers.length;
24412461
const onWorkerClose = () => {

0 commit comments

Comments
 (0)