Skip to content

Commit dbb2ede

Browse files
committed
fix: add more idle timeout options
1 parent 7c1358f commit dbb2ede

File tree

4 files changed

+38
-19
lines changed

4 files changed

+38
-19
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ Options:
5656
This value may be overriden by keep-alive hints from the server.
5757
Default: `4e3` milliseconds (4s).
5858

59+
- `maxIdleTimeout: Number`, the maximum allowed `idleTimeout` when overriden by
60+
keep-alive hints from the server.
61+
Default: `600e3` milliseconds (10min).
62+
63+
- `idleThreshold: Number`, a number subtracted from server keep-alive hints
64+
when overriding `idleTimeout` to account for timing inaccuries caused by e.g.
65+
request/response latency.
66+
Default: `1e3` milliseconds (1s).
67+
5968
- `requestTimeout: Number`, the timeout after which a request will time out.
6069
Monitors time between request being enqueued and receiving
6170
a response. Use `0` to disable it entirely.

lib/client.js

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ const {
4949
kEnqueue,
5050
kKeepAliveTimeout,
5151
kMaxHeadersSize,
52-
kHeadersTimeout
52+
kHeadersTimeout,
53+
kMaxIdleTimeout,
54+
kIdleThreshold
5355
} = require('./symbols')
5456
const makeStream = require('./client-stream')
5557
const makeRequest = require('./client-request')
@@ -69,6 +71,8 @@ class Client extends EventEmitter {
6971
headersTimeout,
7072
socketTimeout,
7173
idleTimeout,
74+
maxIdleTimeout,
75+
idleThreshold,
7276
socketPath,
7377
requestTimeout,
7478
pipelining,
@@ -120,6 +124,18 @@ class Client extends EventEmitter {
120124
throw new InvalidArgumentError('invalid idleTimeout')
121125
}
122126

127+
if (idleTimeout != null && (!Number.isFinite(idleTimeout) || idleTimeout <= 0)) {
128+
throw new InvalidArgumentError('invalid idleTimeout')
129+
}
130+
131+
if (maxIdleTimeout != null && (!Number.isFinite(maxIdleTimeout) || maxIdleTimeout <= 0)) {
132+
throw new InvalidArgumentError('invalid maxIdleTimeout')
133+
}
134+
135+
if (idleThreshold != null && !Number.isFinite(idleThreshold)) {
136+
throw new InvalidArgumentError('invalid idleThreshold')
137+
}
138+
123139
if (requestTimeout != null && !Number.isFinite(requestTimeout)) {
124140
throw new InvalidArgumentError('invalid requestTimeout')
125141
}
@@ -136,7 +152,9 @@ class Client extends EventEmitter {
136152
this[kUrl] = url
137153
this[kSocketPath] = socketPath
138154
this[kSocketTimeout] = socketTimeout == null ? 30e3 : socketTimeout
155+
this[kMaxIdleTimeout] = maxIdleTimeout == null ? 600e3 : maxIdleTimeout
139156
this[kIdleTimeout] = idleTimeout == null ? 4e3 : idleTimeout
157+
this[kIdleThreshold] = idleThreshold == null ? 1e3 : idleThreshold
140158
this[kKeepAliveTimeout] = this[kIdleTimeout]
141159
this[kRequestTimeout] = requestTimeout == null ? 30e3 : requestTimeout
142160
this[kClosed] = false
@@ -494,12 +512,14 @@ class Parser extends HTTPParser {
494512
if (headers['keep-alive']) {
495513
const m = headers['keep-alive'].match(/timeout=(\d+)/)
496514
if (m) {
497-
const timeout = Number(m[1])
498-
if (!timeout) {
515+
const keepAliveTimeout = Math.min(
516+
Number(m[1]) * 1000 - client[kIdleThreshold],
517+
client[kMaxIdleTimeout]
518+
)
519+
if (!keepAliveTimeout || keepAliveTimeout < 1e3) {
499520
client[kReset] = true
500521
} else {
501-
// Set timeout to 500ms less than hint to account for timing inaccuracies.
502-
client[kKeepAliveTimeout] = timeout * 1000 - 500
522+
client[kKeepAliveTimeout] = keepAliveTimeout
503523
}
504524
}
505525
} else {

lib/pool.js

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,15 @@ const {
1212
class Pool {
1313
constructor (url, {
1414
connections,
15-
maxAbortedPayload,
16-
socketTimeout,
17-
requestTimeout,
18-
pipelining,
19-
tls,
20-
socketPath
15+
...options
2116
} = {}) {
2217
if (connections != null && (!Number.isFinite(connections) || connections <= 0)) {
2318
throw new InvalidArgumentError('invalid connections')
2419
}
2520

2621
this[kClients] = Array.from({
2722
length: connections || 10
28-
}, () => new Client(url, {
29-
maxAbortedPayload,
30-
socketTimeout,
31-
requestTimeout,
32-
pipelining,
33-
tls,
34-
socketPath
35-
}))
23+
}, () => new Client(url, options))
3624
}
3725

3826
/* istanbul ignore next: use by benchmark */

lib/symbols.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ module.exports = {
66
kConnect: Symbol('connect'),
77
kSocketTimeout: Symbol('socket timeout'),
88
kIdleTimeout: Symbol('idle timeout'),
9+
kMaxIdleTimeout: Symbol('max idle timeout'),
10+
kIdleThreshold: Symbol('keep alive threshold'),
911
kRequestTimeout: Symbol('request timeout'),
1012
kKeepAliveTimeout: Symbol('keep alive timeout'),
1113
kServerName: Symbol('server name'),

0 commit comments

Comments
 (0)