fix(desktop): tear down SSH lifecycle when a pooled backend is stopped
Idle-reaper and LRU eviction only called stopPoolBackend, which left sshConnections and the keep-alive WS armed on process-less remote descriptors.
This commit is contained in:
@@ -12744,6 +12744,11 @@ async function stopPoolBackend(profile: string) {
|
||||
const entry = backendPool.get(profile)
|
||||
await poolStopper.stop(profile)
|
||||
releaseLocalBackendSlot(entry)
|
||||
// Remote / SSH-isolated pool entries keep `process: null`. Evicting the
|
||||
// descriptor alone leaves sshConnections + the keep-alive WS armed, so
|
||||
// idle-reaper / LRU retirement would pin the tunnel indefinitely (#106935).
|
||||
await sshBootstrapCoordinator.cancelAndWait(profile)
|
||||
await teardownSshConnection(profile)
|
||||
}
|
||||
|
||||
async function teardownPoolBackendAndWait(profile) {
|
||||
|
||||
@@ -70,6 +70,29 @@ describe('main.ts wiring for SSH-isolated keep-alive WS (#106935)', () => {
|
||||
expect(body).toMatch(/sshIsolatedKeepalives\.stop\(\s*scope/)
|
||||
})
|
||||
|
||||
it('stopPoolBackend tears down the matching SSH lifecycle (idle-reaper / LRU)', () => {
|
||||
const fnStart = mainSource.indexOf('async function stopPoolBackend(')
|
||||
expect(fnStart).toBeGreaterThan(-1)
|
||||
|
||||
const nextFn = mainSource.indexOf('\nasync function teardownPoolBackendAndWait(', fnStart + 1)
|
||||
const body = mainSource.slice(fnStart, nextFn === -1 ? fnStart + 400 : nextFn)
|
||||
|
||||
expect(body).toMatch(/sshBootstrapCoordinator\.cancelAndWait\(\s*profile/)
|
||||
expect(body).toMatch(/teardownSshConnection\(\s*profile/)
|
||||
})
|
||||
|
||||
it('idle reaper retires descriptors only through stopPoolBackend', () => {
|
||||
const fnStart = mainSource.indexOf('function startPoolIdleReaper(')
|
||||
expect(fnStart).toBeGreaterThan(-1)
|
||||
|
||||
const nextFn = mainSource.indexOf('\nfunction releaseLocalBackendSlot(', fnStart + 1)
|
||||
const body = mainSource.slice(fnStart, nextFn === -1 ? fnStart + 800 : nextFn)
|
||||
|
||||
expect(body).toContain('stopPoolBackend(profile)')
|
||||
expect(body).not.toMatch(/backendPool\.delete/)
|
||||
expect(body).not.toMatch(/sshConnections\.delete/)
|
||||
})
|
||||
|
||||
it('imports the keep-alive registry from the electron helper (not inline in main)', () => {
|
||||
expect(mainSource).toMatch(/createSshIsolatedKeepaliveRegistry/)
|
||||
expect(mainSource).toMatch(/from '\.\/ssh-isolated-keepalive'/)
|
||||
|
||||
Reference in New Issue
Block a user