fix(server): socket noDelay/keepAlive options were never applied on TCP/UDS listeners, and keep-alive delay was 600ms not 10min#1859
Merged
Conversation
…UDS listeners net.createServer(listener, options) silently ignores the options object (a function first argument becomes the connectionListener), so the noDelay/keepAlive/keepAliveInitialDelay options on the TCP and UDS-mirror listeners created by onSocket() were never applied. Swap to options-first. Also fix keepAliveInitialDelay from 600 to 600_000: the option is in milliseconds and net.Server floors it to whole seconds, so 600 yielded a 0-second initial delay (OS-default keep-alive idle) rather than the 10 minutes the comment intended — including on the TLS listener, which already had the correct argument order. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… not 10 minutes Same unit bug as the threadServer.js listeners: net.Server floors keepAliveInitialDelay to whole seconds, so 600 (ms) yielded a 0-second initial delay (OS-default keep-alive idle) on the HTTP/HTTPS servers and the HTTP UDS mirror rather than the intended 10 minutes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The noDelay/keepAlive/keepAliveInitialDelay trio was repeated at five listener-creation sites and had already drifted; keep it in serverRegistry.ts (imported by both http.ts and threadServer.js) so the values stay uniform. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Code Review
This pull request centralizes socket hygiene defaults (such as noDelay, keepAlive, and keepAliveInitialDelay) into a single exported object socketOptionDefaults to prevent configuration drift across different listener types. It also corrects the keep-alive initial delay from 600ms to 10 minutes (600,000ms) and fixes an argument order bug in createSocketServer calls. A new unit test is added to verify these options. The reviewer suggests using assert.strictEqual instead of assert.equal in the new test to comply with strict assertion standards.
Contributor
|
Reviewed; no blockers found. |
kriszyp
marked this pull request as ready for review
July 18, 2026 13:22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
onSocket()inserver/threads/threadServer.jscreated its plain-TCP listener and the TLS UDS mirror withnet.createServer(listener, options). Node's signature isnet.createServer([options][, connectionListener])— when the first argument is a function it becomes the connection listener and the second argument is silently ignored, sonoDelay/keepAlive/keepAliveInitialDelaywere never applied on those servers. Fixed by swapping to options-first.While auditing the other listener sites, a second latent bug turned up:
keepAliveInitialDelayis in milliseconds andnet.Serverfloors it to whole seconds (~~(ms/1000)), so the value600— commented as "10 minute keep-alive" — floored to a 0-second initial delay everywhere it was applied (the TLS listener and both HTTP server sites). In practice that meantSO_KEEPALIVEenabled with the OS-default idle time (~2 h on Linux), not 10 minutes. Changed to600_000at every site.Since the trio was repeated at five sites and had already drifted, it now lives in one shared
socketOptionDefaultsexport inserverRegistry.ts(a leaf module bothhttp.tsandthreadServer.jsalready import).Behavior changes to weigh (this is the part worth reviewing)
Options that were inert for years now take effect:
noDelay.setNoDelay/setKeepAlive), so no behavior change there — fixed for correctness and consistency.Verification
server.noDelay/keepAlivefalse;600floors to 0 s;600_000yieldssetKeepAlive(true, 600)on the accepted socket's handle.unitTests/apiTests/mqtt-test.mjsasserts the threeserver.socket()-created listeners (TCP, TLS, and the UDS mirror viatls_unixDomainSockets) actually carry the options. Verified it fails against the old code and passes with the fix.main);udsMirror.test.js26/26 passing.Notes
withProxyProtocol(listener)). Whichever lands second has a small, mechanical conflict — the listener argument (wrapped or not) just stays in the second position.socketOptionDefaults).