From 872206f57438d783dd1a3db24cfe7760e0a19e95 Mon Sep 17 00:00:00 2001 From: killagu Date: Sun, 14 Jun 2020 12:39:01 +0800 Subject: [PATCH 1/7] fix: compatible with node v12.16.3 Refs: - https://github.com/nodejs/node/pull/32000 --- lib/agent.js | 60 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/lib/agent.js b/lib/agent.js index 5767abf..7bb1006 100644 --- a/lib/agent.js +++ b/lib/agent.js @@ -85,6 +85,16 @@ class Agent extends OriginalAgent { // including free socket timeout counter this.timeoutSocketCount = 0; this.timeoutSocketCountLastCheck = 0; + + this.on('free', socket => { + // https://github.com/nodejs/node/pull/32000 + // Node.js native agent will check socket timeout eqs agent.options.timeout. + // Use the ttl or freeSocketTimeout to overwrite. + const timeout = this.calcSocketTimeout(socket); + if (timeout > 0 && socket.timeout !== timeout) { + socket.setTimeout(timeout); + } + }); } get freeSocketKeepAliveTimeout() { @@ -102,29 +112,24 @@ class Agent extends OriginalAgent { return this.options.socketActiveTTL; } - keepSocketAlive(socket) { - const result = super.keepSocketAlive(socket); - // should not keepAlive, do nothing - if (!result) return result; - + /** + * return < 0: should free socket + * return >= 0: should update socket timeout + * return undefined: not find custom timeout + * @param socket + * @return {number|undefined} + */ + calcSocketTimeout(socket) { let freeSocketTimeout = this.options.freeSocketTimeout; const socketActiveTTL = this.options.socketActiveTTL; if (socketActiveTTL) { // check socketActiveTTL const aliveTime = Date.now() - socket[SOCKET_CREATED_TIME]; const diff = socketActiveTTL - aliveTime; - // destroy it if (diff <= 0) { - debug('%s(requests: %s, finished: %s) free but need to destroy by TTL, alive %sms(max %sms)', - socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT], - aliveTime, socketActiveTTL); - return false; + return diff; } - if (freeSocketTimeout && diff < freeSocketTimeout) { - debug('%s(requests: %s, finished: %s) free and wait for %sms TTL timeout', - socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT], - diff); freeSocketTimeout = diff; } } @@ -134,12 +139,26 @@ class Agent extends OriginalAgent { // try to use socket custom freeSocketTimeout first, support headers['keep-alive'] // https://github.com/node-modules/urllib/blob/b76053020923f4d99a1c93cf2e16e0c5ba10bacf/lib/urllib.js#L498 const customFreeSocketTimeout = socket.freeSocketTimeout || socket.freeSocketKeepAliveTimeout; - if (customFreeSocketTimeout && customFreeSocketTimeout < freeSocketTimeout) { - freeSocketTimeout = customFreeSocketTimeout; - } - // FIXME: need to make setRequestSocket as a method on Agent class - // then we can reset the agent.options.timeout when free socket is reused. - socket.setTimeout(freeSocketTimeout); + return customFreeSocketTimeout || freeSocketTimeout; + } + } + + keepSocketAlive(socket) { + const result = super.keepSocketAlive(socket); + // should not keepAlive, do nothing + if (!result) return result; + + const customTimeout = this.calcSocketTimeout(socket); + if (typeof customTimeout === 'undefined') { + return true; + } + if (customTimeout <= 0) { + debug('%s(requests: %s, finished: %s) free but need to destroy by TTL, request count %s, diff is %s', + socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT], customTimeout); + return false; + } + if (socket.timeout !== customTimeout) { + socket.setTimeout(customTimeout); } return true; } @@ -362,7 +381,6 @@ function installListeners(agent, socket, options) { // pool because it'll be locked up indefinitely socket.removeListener('close', onClose); socket.removeListener('error', onError); - socket.removeListener('free', onFree); socket.removeListener('timeout', onTimeout); socket.removeListener('agentRemove', onRemove); } From 719a4e70c981fb43af91aa9715e1344e283f3a31 Mon Sep 17 00:00:00 2001 From: killagu Date: Sun, 14 Jun 2020 12:41:29 +0800 Subject: [PATCH 2/7] docs: fix comments --- lib/agent.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/agent.js b/lib/agent.js index 7bb1006..22c21d4 100644 --- a/lib/agent.js +++ b/lib/agent.js @@ -113,8 +113,8 @@ class Agent extends OriginalAgent { } /** - * return < 0: should free socket - * return >= 0: should update socket timeout + * return <= 0: should free socket + * return > 0: should update socket timeout * return undefined: not find custom timeout * @param socket * @return {number|undefined} From 92f3ec8ade61e8deb54b05e427dccb3add434ddb Mon Sep 17 00:00:00 2001 From: killagu Date: Sun, 14 Jun 2020 12:43:54 +0800 Subject: [PATCH 3/7] ci: add node 14 --- .github/workflows/nodejs.yml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 4060930..d1a6443 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - node-version: [8.x, 10.x, 12.x] + node-version: [8.x, 10.x, 12.x, 14.x] os: [ubuntu-latest] steps: diff --git a/package.json b/package.json index 55a3fac..9948c18 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "os": { "github": "linux" }, - "version": "8, 10, 12" + "version": "8, 10, 12, 14" }, "author": "fengmk2 (https://fengmk2.com)", "license": "MIT" From f8ee567a38127480626602435e3757ace9a6dccb Mon Sep 17 00:00:00 2001 From: killagu Date: Sun, 14 Jun 2020 12:45:44 +0800 Subject: [PATCH 4/7] f --- lib/agent.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/agent.js b/lib/agent.js index 22c21d4..2dd8141 100644 --- a/lib/agent.js +++ b/lib/agent.js @@ -381,6 +381,7 @@ function installListeners(agent, socket, options) { // pool because it'll be locked up indefinitely socket.removeListener('close', onClose); socket.removeListener('error', onError); + socket.removeListener('free', onFree); socket.removeListener('timeout', onTimeout); socket.removeListener('agentRemove', onRemove); } From 89d323c0daf990a2063c7b04516b5ebc94eea779 Mon Sep 17 00:00:00 2001 From: killagu Date: Sun, 14 Jun 2020 12:56:37 +0800 Subject: [PATCH 5/7] f --- test/server_timeout.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/server_timeout.test.js b/test/server_timeout.test.js index 4102e04..a04ad2f 100644 --- a/test/server_timeout.test.js +++ b/test/server_timeout.test.js @@ -29,7 +29,7 @@ describe('test/server_timeout.test.js', () => { clearInterval(timer); }); - it('should handle Keep-Alive header and not throw reset error', done => { + it.only('should handle Keep-Alive header and not throw reset error', done => { const keepaliveAgent = new Agent({ keepAlive: true, }); @@ -57,7 +57,7 @@ describe('test/server_timeout.test.js', () => { if (m) { const keepAliveTimeout = parseInt(m[1]) * 1000 - 500; if (keepAliveTimeout > 0) { - res.socket.freeSocketKeepAliveTimeout = keepAliveTimeout; + req.socket.freeSocketKeepAliveTimeout = keepAliveTimeout; } } if (count > 5) { From c4c754902578b1c9f94f51b2aa909e6e5b05254c Mon Sep 17 00:00:00 2001 From: killagu Date: Sun, 14 Jun 2020 12:57:20 +0800 Subject: [PATCH 6/7] f --- test/server_timeout.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/server_timeout.test.js b/test/server_timeout.test.js index a04ad2f..5c50d5b 100644 --- a/test/server_timeout.test.js +++ b/test/server_timeout.test.js @@ -29,7 +29,7 @@ describe('test/server_timeout.test.js', () => { clearInterval(timer); }); - it.only('should handle Keep-Alive header and not throw reset error', done => { + it('should handle Keep-Alive header and not throw reset error', done => { const keepaliveAgent = new Agent({ keepAlive: true, }); From 175920fee0bdd807c1f05d7f8aca0e6f77580d00 Mon Sep 17 00:00:00 2001 From: killagu Date: Sun, 14 Jun 2020 13:06:14 +0800 Subject: [PATCH 7/7] f --- lib/agent.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/agent.js b/lib/agent.js index 2dd8141..d0294a6 100644 --- a/lib/agent.js +++ b/lib/agent.js @@ -112,14 +112,12 @@ class Agent extends OriginalAgent { return this.options.socketActiveTTL; } - /** - * return <= 0: should free socket - * return > 0: should update socket timeout - * return undefined: not find custom timeout - * @param socket - * @return {number|undefined} - */ calcSocketTimeout(socket) { + /** + * return <= 0: should free socket + * return > 0: should update socket timeout + * return undefined: not find custom timeout + */ let freeSocketTimeout = this.options.freeSocketTimeout; const socketActiveTTL = this.options.socketActiveTTL; if (socketActiveTTL) {