Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to set TCP keepalive #1904

Merged
merged 5 commits into from
Feb 4, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/api/Dispatcher.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo
* **bodyTimeout** `number | null` (optional) - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 30 seconds.
* **headersTimeout** `number | null` (optional) - The amount of time the parser will wait to receive the complete HTTP headers while not sending the request. Defaults to 30 seconds.
* **throwOnError** `boolean` (optional) - Default: `false` - Whether Undici should throw an error upon receiving a 4xx or 5xx response from the server.
* **tcpKeepAliveInterval** `number | null` (optional) - Default: `60000` - TCP keepalive interval for the socket in milliseconds

#### Parameter: `DispatchHandler`

Expand Down
15 changes: 13 additions & 2 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ const {
kDispatch,
kInterceptors,
kLocalAddress,
kMaxResponseSize
kMaxResponseSize,
kTcpKeepAliveInterval
} = require('./core/symbols')

const kClosedResolve = Symbol('kClosedResolve')
Expand Down Expand Up @@ -107,7 +108,8 @@ class Client extends DispatcherBase {
connect,
maxRequestsPerClient,
localAddress,
maxResponseSize
maxResponseSize,
tcpKeepAliveInterval
} = {}) {
super()

Expand Down Expand Up @@ -163,6 +165,10 @@ class Client extends DispatcherBase {
throw new InvalidArgumentError('bodyTimeout must be a positive integer or zero')
}

if (tcpKeepAliveInterval != null && (!Number.isInteger(tcpKeepAliveInterval) || tcpKeepAliveInterval < 0)) {
throw new InvalidArgumentError('tcpKeepAliveInterval must be a positive integer or zero')
}

if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') {
throw new InvalidArgumentError('connect must be a function or an object')
}
Expand Down Expand Up @@ -212,6 +218,7 @@ class Client extends DispatcherBase {
this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}\r\n`
this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 30e3
this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 30e3
this[kTcpKeepAliveInterval] = tcpKeepAliveInterval != null ? tcpKeepAliveInterval : 60e3
this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength
this[kMaxRedirections] = maxRedirections
this[kMaxRequests] = maxRequestsPerClient
Expand Down Expand Up @@ -1349,6 +1356,10 @@ function write (client, request) {

const socket = client[kSocket]

if (client[kTcpKeepAliveInterval]) {
socket.setKeepAlive(true, client[kTcpKeepAliveInterval])
}

try {
request.onConnect((err) => {
if (request.aborted || request.completed) {
Expand Down
1 change: 1 addition & 0 deletions lib/core/symbols.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module.exports = {
kKeepAlive: Symbol('keep alive'),
kHeadersTimeout: Symbol('headers timeout'),
kBodyTimeout: Symbol('body timeout'),
kTcpKeepAliveInterval: Symbol('tcp keep alive interval'),
kServerName: Symbol('server name'),
kLocalAddress: Symbol('local address'),
kHost: Symbol('host'),
Expand Down
2 changes: 2 additions & 0 deletions types/client.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ declare namespace Client {
maxRequestsPerClient?: number;
/** Max response body size in bytes, -1 is disabled */
maxResponseSize?: number | null;
/** TCP keepalive interval for the socket in milliseconds. Default: `60e3` milliseconds (60s) */
tcpKeepAliveInterval?: number | null;
xconverge marked this conversation as resolved.
Show resolved Hide resolved

interceptors?: {Client: readonly DispatchInterceptor[] | undefined}
}
Expand Down