From c9074592d27de2217d94914500c757d544403561 Mon Sep 17 00:00:00 2001 From: Subhi Al Hasan Date: Sat, 23 Oct 2021 02:20:31 +0200 Subject: [PATCH] http: change totalSocketCount only on socket creation or when the socket is closed --- lib/_http_agent.js | 4 ++-- test/parallel/test-http-agent-keepalive.js | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/_http_agent.js b/lib/_http_agent.js index a42c0e83992b1f..c966cb1957242a 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -284,7 +284,6 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */, this.reuseSocket(socket, req); setRequestSocket(this, req, socket); ArrayPrototypePush(this.sockets[name], socket); - this.totalSocketCount++; } else if (sockLen < this.maxSockets && this.totalSocketCount < this.maxTotalSockets) { debug('call onSocket', sockLen, freeLen); @@ -383,6 +382,7 @@ function installListeners(agent, s, options) { // This is the only place where sockets get removed from the Agent. // If you want to remove a socket from the pool, just close it. // All socket errors end in a close event anyway. + agent.totalSocketCount--; agent.removeSocket(s, options); } s.on('close', onClose); @@ -406,6 +406,7 @@ function installListeners(agent, s, options) { // (defined by WebSockets) where we need to remove a socket from the // pool because it'll be locked up indefinitely debug('CLIENT socket onRemove'); + anget.totalSocketCount--; agent.removeSocket(s, options); s.removeListener('close', onClose); s.removeListener('free', onFree); @@ -438,7 +439,6 @@ Agent.prototype.removeSocket = function removeSocket(s, options) { // Don't leak if (sockets[name].length === 0) delete sockets[name]; - this.totalSocketCount--; } } } diff --git a/test/parallel/test-http-agent-keepalive.js b/test/parallel/test-http-agent-keepalive.js index a1f902fab091e1..5363c7d98fb654 100644 --- a/test/parallel/test-http-agent-keepalive.js +++ b/test/parallel/test-http-agent-keepalive.js @@ -59,6 +59,7 @@ function checkDataAndSockets(body) { assert.strictEqual(body.toString(), 'hello world'); assert.strictEqual(agent.sockets[name].length, 1); assert.strictEqual(agent.freeSockets[name], undefined); + assert.strictEqual(agent.totalSocketCount, 1); } function second() { @@ -73,6 +74,7 @@ function second() { process.nextTick(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name].length, 1); + assert.strictEqual(agent.totalSocketCount, 1); remoteClose(); })); })); @@ -91,10 +93,12 @@ function remoteClose() { process.nextTick(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name].length, 1); + assert.strictEqual(agent.totalSocketCount, 1); // Waiting remote server close the socket setTimeout(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name], undefined); + assert.strictEqual(agent.totalSocketCount, 0); remoteError(); }), common.platformTimeout(200)); })); @@ -110,10 +114,12 @@ function remoteError() { assert.strictEqual(err.message, 'socket hang up'); assert.strictEqual(agent.sockets[name].length, 1); assert.strictEqual(agent.freeSockets[name], undefined); + assert.strictEqual(agent.totalSocketCount, 1); // Wait socket 'close' event emit setTimeout(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name], undefined); + assert.strictEqual(agent.totalSocketCount, 0); server.close(); }), common.platformTimeout(1)); })); @@ -132,6 +138,7 @@ server.listen(0, common.mustCall(() => { process.nextTick(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name].length, 1); + assert.strictEqual(agent.totalSocketCount, 1); second(); })); }));