perf(wsl): release environment probe deadline timers

This commit is contained in:
Orca Worker
2026-09-11 21:35:47 -07:00
parent 20ab995065
commit 8fdffc6bf6
2 changed files with 34 additions and 2 deletions
@@ -58,6 +58,33 @@ describe('probing', () => {
await getWslGuestEnvironment('Debian')
expect(runProcessMock).toHaveBeenCalledTimes(2)
})
it('does not retain deadline timers after a concurrent probe settles', async () => {
vi.useFakeTimers()
try {
respondWithPayload(GOOD)
await Promise.all(Array.from({ length: 32 }, () => getWslGuestEnvironment('Ubuntu')))
expect(vi.getTimerCount()).toBe(0)
expect(runProcessMock).toHaveBeenCalledTimes(1)
} finally {
vi.useRealTimers()
}
})
it('reads a warm cache without allocating deadline timers', async () => {
respondWithPayload(GOOD)
const environment = await getWslGuestEnvironment('Ubuntu')
const timeout = vi.spyOn(globalThis, 'setTimeout')
try {
for (let index = 0; index < 100; index++) {
expect(await getWslGuestEnvironment('Ubuntu')).toBe(environment)
}
expect(timeout).not.toHaveBeenCalled()
expect(runProcessMock).toHaveBeenCalledTimes(1)
} finally {
timeout.mockRestore()
}
})
})
describe('bad answers are not cached as good ones', () => {
+7 -2
View File
@@ -125,6 +125,10 @@ export function getWslGuestEnvironment(
budgetMs = PROBE_TIMEOUT_MS
): Promise<WslGuestEnvironment | null> {
const key = cacheKey(distro)
const cached = resolved.get(key)
if (cached) {
return Promise.resolve(cached)
}
const retry = retryAfter.get(key)
if (retry !== undefined && Date.now() >= retry) {
inFlight.delete(key)
@@ -154,13 +158,14 @@ export function getWslGuestEnvironment(
// Why race: joining an in-flight probe used to mean waiting out the
// *starter's* budget, so a joiner could reach its own command with 1ms --
// the exact hazard the budget plumbing was added to remove.
let timer: ReturnType<typeof setTimeout>
return Promise.race([
existing,
new Promise<null>((resolve) => {
const timer = setTimeout(() => resolve(null), budgetMs)
timer = setTimeout(() => resolve(null), budgetMs)
timer.unref?.()
})
])
]).finally(() => clearTimeout(timer))
}
// Store before awaiting so a burst collapses into one probe.
// Why catch: runProcess REJECTS when the child cannot be started (ENOENT on a