From 0065a2003a1e64ea0a791c7b91a4559701823fa0 Mon Sep 17 00:00:00 2001 From: Thomas Carmet <8408330+tcarmet@users.noreply.github.com> Date: Tue, 4 Aug 2026 12:03:25 -0700 Subject: [PATCH] CLDSRV-968: Expire idle keep-alive sockets in the functional test client The SDK agents in the aws-node-sdk test client enable keepAlive without an idle timeout, so pooled sockets are never expired client-side. Node's HTTP server closes idle keep-alive connections after 5s and advertises `Keep-Alive: timeout=5`, but the agent only honours that hint when it already has a non-zero timeout of its own. Without one, a burst of requests issued after an idle period can be written to connections the server has already closed, failing with ECONNRESET ("socket hang up"). Set a 4s agent idle timeout so the client retires sockets before the server does. This only destroys sockets sitting in the free pool; in-flight requests stay governed by requestTimeout. --- .../functional/aws-node-sdk/test/support/config.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/functional/aws-node-sdk/test/support/config.js b/tests/functional/aws-node-sdk/test/support/config.js index 28bc1cc9ba..c6065543c9 100644 --- a/tests/functional/aws-node-sdk/test/support/config.js +++ b/tests/functional/aws-node-sdk/test/support/config.js @@ -30,6 +30,18 @@ const DEFAULT_GLOBAL_OPTIONS = { // timeout. const REQUEST_TIMEOUT = 30000; +// Idle timeout for pooled keep-alive sockets, which must stay below the +// server's own keep-alive timeout. Node's HTTP server closes idle keep-alive +// connections after 5s and advertises that as `Keep-Alive: timeout=5`, but the +// agent only acts on the hint when it already has a non-zero timeout of its own +// (`agentTimeout = this.options.timeout || 0`, and the hint can only lower an +// existing value). Without one, the agent keeps pooled sockets forever and +// eventually writes to connections the server has already closed, which +// surfaces as ECONNRESET ("socket hang up"). This only ever destroys sockets +// sitting in the free pool: an in-flight request is governed by +// REQUEST_TIMEOUT, which the SDK applies to the socket for its duration. +const AGENT_IDLE_TIMEOUT = 4000; + const DEFAULT_MEM_OPTIONS = { endpoint: `${transport}://127.0.0.1:8000`, port: 8000, @@ -43,6 +55,7 @@ const DEFAULT_MEM_OPTIONS = { maxSockets: 200, keepAlive: true, keepAliveMsecs: 1000, + timeout: AGENT_IDLE_TIMEOUT, }), }), }; @@ -57,6 +70,7 @@ const DEFAULT_AWS_OPTIONS = { maxSockets: 200, keepAlive: true, keepAliveMsecs: 1000, + timeout: AGENT_IDLE_TIMEOUT, }), }), };