diff --git a/src/main/git/git-capability-state.test.ts b/src/main/git/git-capability-state.test.ts index 845c2f47bf8..f1f102570b4 100644 --- a/src/main/git/git-capability-state.test.ts +++ b/src/main/git/git-capability-state.test.ts @@ -35,6 +35,19 @@ describe('Git capability execution-host state', () => { ) }) + it('bounds local capability entries during WSL distro churn', () => { + const first = getLocalGitCapabilityCache({ wslDistro: 'first-distro' }) + first.rememberUnsupported('worktree-list-path-format') + for (let index = 0; index < 132; index += 1) { + getLocalGitCapabilityCache({ wslDistro: `distro-${index}` }) + } + expect( + getLocalGitCapabilityCache({ wslDistro: 'first-distro' }).shouldTry( + 'worktree-list-path-format' + ) + ).toBe(true) + }) + it('shares one SSH provider lifetime without leaking into a replacement provider', () => { const provider = createProviderIdentity() const replacementProvider = createProviderIdentity() diff --git a/src/main/git/git-capability-state.ts b/src/main/git/git-capability-state.ts index d998c21ee75..11ca33790ce 100644 --- a/src/main/git/git-capability-state.ts +++ b/src/main/git/git-capability-state.ts @@ -13,6 +13,7 @@ type LocalGitCapabilityTarget = { } const localCapabilitiesByExecutionHost = new Map() +const MAX_LOCAL_GIT_CAPABILITY_HOSTS = 128 // Why: reconnecting creates a new provider, while concurrent IPC/runtime users // of one SSH connection must share the same remote Git capability results. let sshCapabilitiesByProvider = new WeakMap() @@ -30,7 +31,15 @@ export function getLocalGitCapabilityCache( let cache = localCapabilitiesByExecutionHost.get(executionHost) if (!cache) { cache = new GitCapabilityCache() - localCapabilitiesByExecutionHost.set(executionHost, cache) + } + localCapabilitiesByExecutionHost.delete(executionHost) + localCapabilitiesByExecutionHost.set(executionHost, cache) + while (localCapabilitiesByExecutionHost.size > MAX_LOCAL_GIT_CAPABILITY_HOSTS) { + const oldest = localCapabilitiesByExecutionHost.keys().next().value + if (oldest === undefined) { + break + } + localCapabilitiesByExecutionHost.delete(oldest) } return cache }