Cache https.Agent and Dispatcher per cluster/user pair to fix FD leaks on Watch reconnection#2904
Cache https.Agent and Dispatcher per cluster/user pair to fix FD leaks on Watch reconnection#2904Copilot wants to merge 4 commits into
Conversation
|
…ubeConfig Fixes socket/FD leaks caused by creating a new https.Agent on every Watch reconnection or API call. - Add `agentCache` (Map keyed by "clusterName::userName") to reuse agent instances across repeated calls with the same cluster/user. - Add `dispatcherCache` (same key) to reuse undici Dispatcher instances across repeated applySecurityAuthentication() calls. - Add private `getAgentCacheKey()` helper that builds the key from the current cluster name and user name — consistent with the comment from @brendandburns about keying off the user/cluster tuple. - Add four new tests in config_test.ts verifying same-instance reuse and distinct instances for different cluster/user combinations.
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: Copilot The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
I'm worried that using string concatenation to build the hash key may lead to unexpected (and hard to debug) conflicts, is there a better hashing function you can think of? |
|
@copilot I'm worried that using string concatenation to build the hash key may lead to unexpected (and hard to debug) conflicts, is there a better hashing function you can think of? |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: Copilot The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Good catch. Switched to |
KubeConfig.createAgent()andcreateDispatcher()unconditionally construct a new instance on every call. WithWatch's reconnect pattern, this leaks a new socket pool each cycle — orphaned agents are not promptly GC'd due to reference chains throughnode-fetchresponse body streams, causing steady FD growth and eventualEMFILE.Changes
src/config.tsagentCache: Map<string, Agent>anddispatcherCache: Map<string, Dispatcher | undefined>toKubeConfig, keyed by"clusterName::userName"(the tuple that uniquely determines TLS config and auth)createAgent()andcreateDispatcher()now return a cached instance on subsequent calls for the same cluster/user pair, constructing only on first usegetAgentCacheKey(cluster)helpersrc/config_test.tsBehavior
The cache is keyed by cluster+user names rather than a single global entry, so multi-cluster configs that switch context get the correct per-endpoint agent.