mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00
http: add Agent.agentKeepAliveTimeoutBuffer option
Some checks failed
Coverage Windows / coverage-windows (push) Waiting to run
Coverage Linux (without intl) / coverage-linux-without-intl (push) Failing after 1m45s
Coverage Linux / coverage-linux (push) Failing after 1m1s
Test and upload documentation to artifacts / build-docs (push) Failing after 6m37s
Linters / lint-addon-docs (push) Successful in 2m28s
Linters / lint-cpp (push) Successful in 4m20s
Linters / format-cpp (push) Has been skipped
Linters / lint-py (push) Successful in 2m39s
Linters / lint-yaml (push) Successful in 2m32s
Linters / lint-sh (push) Failing after 1m41s
Linters / lint-codeowners (push) Failing after 56s
Linters / lint-pr-url (push) Has been skipped
Linters / lint-readme (push) Successful in 1m24s
Notify on Push / Notify on Force Push on `main` (push) Has been skipped
Linters / lint-js-and-md (push) Successful in 14m58s
Notify on Push / Notify on Push on `main` that lacks metadata (push) Has been skipped
Scorecard supply-chain security / Scorecard analysis (push) Failing after 52s
Some checks failed
Coverage Windows / coverage-windows (push) Waiting to run
Coverage Linux (without intl) / coverage-linux-without-intl (push) Failing after 1m45s
Coverage Linux / coverage-linux (push) Failing after 1m1s
Test and upload documentation to artifacts / build-docs (push) Failing after 6m37s
Linters / lint-addon-docs (push) Successful in 2m28s
Linters / lint-cpp (push) Successful in 4m20s
Linters / format-cpp (push) Has been skipped
Linters / lint-py (push) Successful in 2m39s
Linters / lint-yaml (push) Successful in 2m32s
Linters / lint-sh (push) Failing after 1m41s
Linters / lint-codeowners (push) Failing after 56s
Linters / lint-pr-url (push) Has been skipped
Linters / lint-readme (push) Successful in 1m24s
Notify on Push / Notify on Force Push on `main` (push) Has been skipped
Linters / lint-js-and-md (push) Successful in 14m58s
Notify on Push / Notify on Push on `main` that lacks metadata (push) Has been skipped
Scorecard supply-chain security / Scorecard analysis (push) Failing after 52s
PR-URL: https://github.com/nodejs/node/pull/59315 Reviewed-By: Jason Zhang <xzha4350@gmail.com>
This commit is contained in:
parent
bb6e8351c7
commit
a4b4eca94c
3 changed files with 64 additions and 3 deletions
|
@ -116,6 +116,10 @@ http.get({
|
|||
<!-- YAML
|
||||
added: v0.3.4
|
||||
changes:
|
||||
- version:
|
||||
- REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/59315
|
||||
description: Add support for `agentKeepAliveTimeoutBuffer`.
|
||||
- version:
|
||||
- v24.5.0
|
||||
pr-url: https://github.com/nodejs/node/pull/58980
|
||||
|
@ -156,6 +160,12 @@ changes:
|
|||
the [initial delay][]
|
||||
for TCP Keep-Alive packets. Ignored when the
|
||||
`keepAlive` option is `false` or `undefined`. **Default:** `1000`.
|
||||
* `agentKeepAliveTimeoutBuffer` {number} Milliseconds to subtract from
|
||||
the server-provided `keep-alive: timeout=...` hint when determining socket
|
||||
expiration time. This buffer helps ensure the agent closes the socket
|
||||
slightly before the server does, reducing the chance of sending a request
|
||||
on a socket that’s about to be closed by the server.
|
||||
**Default:** `1000`.
|
||||
* `maxSockets` {number} Maximum number of sockets to allow per host.
|
||||
If the same host opens multiple concurrent connections, each request
|
||||
will use new socket until the `maxSockets` value is reached.
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
'use strict';
|
||||
|
||||
const {
|
||||
NumberIsFinite,
|
||||
NumberParseInt,
|
||||
ObjectKeys,
|
||||
ObjectSetPrototypeOf,
|
||||
|
@ -60,8 +61,6 @@ const kOnKeylog = Symbol('onkeylog');
|
|||
const kRequestOptions = Symbol('requestOptions');
|
||||
const kRequestAsyncResource = Symbol('requestAsyncResource');
|
||||
|
||||
// TODO(jazelly): make this configurable
|
||||
const HTTP_AGENT_KEEP_ALIVE_TIMEOUT_BUFFER = 1000;
|
||||
// New Agent code.
|
||||
|
||||
// The largest departure from the previous implementation is that
|
||||
|
@ -114,6 +113,14 @@ function Agent(options) {
|
|||
this.scheduling = this.options.scheduling || 'lifo';
|
||||
this.maxTotalSockets = this.options.maxTotalSockets;
|
||||
this.totalSocketCount = 0;
|
||||
|
||||
this.agentKeepAliveTimeoutBuffer =
|
||||
typeof this.options.agentKeepAliveTimeoutBuffer === 'number' &&
|
||||
this.options.agentKeepAliveTimeoutBuffer >= 0 &&
|
||||
NumberIsFinite(this.options.agentKeepAliveTimeoutBuffer) ?
|
||||
this.options.agentKeepAliveTimeoutBuffer :
|
||||
1000;
|
||||
|
||||
const proxyEnv = this.options.proxyEnv;
|
||||
if (typeof proxyEnv === 'object' && proxyEnv !== null) {
|
||||
this[kProxyConfig] = parseProxyConfigFromEnv(proxyEnv, this.protocol, this.keepAlive);
|
||||
|
@ -559,7 +566,7 @@ Agent.prototype.keepSocketAlive = function keepSocketAlive(socket) {
|
|||
if (hint) {
|
||||
// Let the timer expire before the announced timeout to reduce
|
||||
// the likelihood of ECONNRESET errors
|
||||
let serverHintTimeout = (NumberParseInt(hint) * 1000) - HTTP_AGENT_KEEP_ALIVE_TIMEOUT_BUFFER;
|
||||
let serverHintTimeout = (NumberParseInt(hint) * 1000) - this.agentKeepAliveTimeoutBuffer;
|
||||
serverHintTimeout = serverHintTimeout > 0 ? serverHintTimeout : 0;
|
||||
if (serverHintTimeout === 0) {
|
||||
// Cannot safely reuse the socket because the server timeout is
|
||||
|
|
44
test/parallel/test-http-agent-keep-alive-timeout-buffer.js
Normal file
44
test/parallel/test-http-agent-keep-alive-timeout-buffer.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
|
||||
// Ensure agentKeepAliveTimeoutBuffer option sets the correct value or falls back to default.
|
||||
{
|
||||
const agent1 = new http.Agent({ agentKeepAliveTimeoutBuffer: 1500, keepAlive: true });
|
||||
assert.strictEqual(agent1.agentKeepAliveTimeoutBuffer, 1500);
|
||||
|
||||
const agent2 = new http.Agent({ agentKeepAliveTimeoutBuffer: -100, keepAlive: true });
|
||||
assert.strictEqual(agent2.agentKeepAliveTimeoutBuffer, 1000);
|
||||
|
||||
const agent3 = new http.Agent({ agentKeepAliveTimeoutBuffer: Infinity, keepAlive: true });
|
||||
assert.strictEqual(agent3.agentKeepAliveTimeoutBuffer, 1000);
|
||||
|
||||
const agent4 = new http.Agent({ keepAlive: true });
|
||||
assert.strictEqual(agent4.agentKeepAliveTimeoutBuffer, 1000);
|
||||
}
|
||||
|
||||
// Integration test with server sending Keep-Alive timeout header.
|
||||
{
|
||||
const SERVER_TIMEOUT = 3;
|
||||
const BUFFER = 1500;
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Keep-Alive', `timeout=${SERVER_TIMEOUT}`);
|
||||
res.end('ok');
|
||||
});
|
||||
|
||||
server.listen(0, common.mustCall(() => {
|
||||
const agent = new http.Agent({ agentKeepAliveTimeoutBuffer: BUFFER, keepAlive: true });
|
||||
assert.strictEqual(agent.agentKeepAliveTimeoutBuffer, BUFFER);
|
||||
|
||||
http.get({ port: server.address().port, agent }, (res) => {
|
||||
res.resume();
|
||||
res.on('end', () => {
|
||||
agent.destroy();
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
}));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue