Skip to content

Commit 6ae202f

Browse files
haramjtargos
authored andcommitted
http: add Agent.agentKeepAliveTimeoutBuffer option
PR-URL: #59315 Reviewed-By: Jason Zhang <xzha4350@gmail.com>
1 parent 64ffde6 commit 6ae202f

3 files changed

Lines changed: 64 additions & 3 deletions

File tree

‎doc/api/http.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ http.get({
116116
<!-- YAML
117117
added: v0.3.4
118118
changes:
119+
- version:
120+
- REPLACEME
121+
pr-url: https://github.com/nodejs/node/pull/59315
122+
description: Add support for `agentKeepAliveTimeoutBuffer`.
119123
- version:
120124
- v24.5.0
121125
pr-url: https://github.com/nodejs/node/pull/58980
@@ -156,6 +160,12 @@ changes:
156160
the [initial delay][]
157161
for TCP Keep-Alive packets. Ignored when the
158162
`keepAlive` option is `false` or `undefined`. **Default:**`1000`.
163+
*`agentKeepAliveTimeoutBuffer` {number} Milliseconds to subtract from
164+
the server-provided `keep-alive: timeout=...` hint when determining socket
165+
expiration time. This buffer helps ensure the agent closes the socket
166+
slightly before the server does, reducing the chance of sending a request
167+
on a socket that’s about to be closed by the server.
168+
**Default:**`1000`.
159169
*`maxSockets` {number} Maximum number of sockets to allow per host.
160170
If the same host opens multiple concurrent connections, each request
161171
will use new socket until the `maxSockets` value is reached.

‎lib/_http_agent.js‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
'use strict';
2323

2424
const{
25+
NumberIsFinite,
2526
NumberParseInt,
2627
ObjectKeys,
2728
ObjectSetPrototypeOf,
@@ -60,8 +61,6 @@ const kOnKeylog = Symbol('onkeylog');
6061
constkRequestOptions=Symbol('requestOptions');
6162
constkRequestAsyncResource=Symbol('requestAsyncResource');
6263

63-
// TODO(jazelly): make this configurable
64-
constHTTP_AGENT_KEEP_ALIVE_TIMEOUT_BUFFER=1000;
6564
// New Agent code.
6665

6766
// The largest departure from the previous implementation is that
@@ -114,6 +113,14 @@ function Agent(options) {
114113
this.scheduling=this.options.scheduling||'lifo';
115114
this.maxTotalSockets=this.options.maxTotalSockets;
116115
this.totalSocketCount=0;
116+
117+
this.agentKeepAliveTimeoutBuffer=
118+
typeofthis.options.agentKeepAliveTimeoutBuffer==='number'&&
119+
this.options.agentKeepAliveTimeoutBuffer>=0&&
120+
NumberIsFinite(this.options.agentKeepAliveTimeoutBuffer) ?
121+
this.options.agentKeepAliveTimeoutBuffer :
122+
1000;
123+
117124
constproxyEnv=this.options.proxyEnv;
118125
if(typeofproxyEnv==='object'&&proxyEnv!==null){
119126
this[kProxyConfig]=parseProxyConfigFromEnv(proxyEnv,this.protocol,this.keepAlive);
@@ -559,7 +566,7 @@ Agent.prototype.keepSocketAlive = function keepSocketAlive(socket) {
559566
if(hint){
560567
// Let the timer expire before the announced timeout to reduce
561568
// the likelihood of ECONNRESET errors
562-
letserverHintTimeout=(NumberParseInt(hint)*1000)-HTTP_AGENT_KEEP_ALIVE_TIMEOUT_BUFFER;
569+
letserverHintTimeout=(NumberParseInt(hint)*1000)-this.agentKeepAliveTimeoutBuffer;
563570
serverHintTimeout=serverHintTimeout>0 ? serverHintTimeout : 0;
564571
if(serverHintTimeout===0){
565572
// Cannot safely reuse the socket because the server timeout is
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'use strict';
2+
3+
constcommon=require('../common');
4+
constassert=require('assert');
5+
consthttp=require('http');
6+
7+
// Ensure agentKeepAliveTimeoutBuffer option sets the correct value or falls back to default.
8+
{
9+
constagent1=newhttp.Agent({agentKeepAliveTimeoutBuffer: 1500,keepAlive: true});
10+
assert.strictEqual(agent1.agentKeepAliveTimeoutBuffer,1500);
11+
12+
constagent2=newhttp.Agent({agentKeepAliveTimeoutBuffer: -100,keepAlive: true});
13+
assert.strictEqual(agent2.agentKeepAliveTimeoutBuffer,1000);
14+
15+
constagent3=newhttp.Agent({agentKeepAliveTimeoutBuffer: Infinity,keepAlive: true});
16+
assert.strictEqual(agent3.agentKeepAliveTimeoutBuffer,1000);
17+
18+
constagent4=newhttp.Agent({keepAlive: true});
19+
assert.strictEqual(agent4.agentKeepAliveTimeoutBuffer,1000);
20+
}
21+
22+
// Integration test with server sending Keep-Alive timeout header.
23+
{
24+
constSERVER_TIMEOUT=3;
25+
constBUFFER=1500;
26+
27+
constserver=http.createServer((req,res)=>{
28+
res.setHeader('Keep-Alive',`timeout=${SERVER_TIMEOUT}`);
29+
res.end('ok');
30+
});
31+
32+
server.listen(0,common.mustCall(()=>{
33+
constagent=newhttp.Agent({agentKeepAliveTimeoutBuffer: BUFFER,keepAlive: true});
34+
assert.strictEqual(agent.agentKeepAliveTimeoutBuffer,BUFFER);
35+
36+
http.get({port: server.address().port, agent },(res)=>{
37+
res.resume();
38+
res.on('end',()=>{
39+
agent.destroy();
40+
server.close();
41+
});
42+
});
43+
}));
44+
}

0 commit comments

Comments
 (0)