fix: fence raced SSH lease replacement

This commit is contained in:
Brennan Benson
2026-07-13 18:24:56 -07:00
parent 87d4019518
commit 28c2ba5daa
2 changed files with 63 additions and 1 deletions
@@ -258,6 +258,68 @@ describe('SSH relay generation reattach', () => {
}
})
it('does not publish a stale attach over a replacement lease created in flight', async () => {
const dir = mkdtempSync(join(tmpdir(), 'orca-ssh-lease-replacement-'))
const store = new Store({ dataFile: join(dir, 'state.json') })
try {
store.upsertSshRemotePtyLease({
targetId: 'target-1',
ptyId: 'pty-recycled',
tabId: 'tab-old',
state: 'detached'
})
const { mockConn, mockPortForward, getMainWindow, mockWindow } = createMockDeps()
let resolveAttach!: (value: { replay: string }) => void
const attachForReconnect = vi.fn().mockReturnValue(
new Promise<{ replay: string }>((resolve) => {
resolveAttach = resolve
})
)
vi.mocked(getSshPtyProvider).mockReturnValue({
attachForReconnect,
getRelayInstanceId: () => 'relay-current',
dispose: vi.fn()
} as unknown as ReturnType<typeof getSshPtyProvider>)
vi.mocked(getPtyIdsForConnection).mockReturnValue([])
const session = new SshRelaySession('target-1', getMainWindow, store, mockPortForward)
const establishing = session.establish(mockConn)
await vi.waitFor(() =>
expect(attachForReconnect).toHaveBeenCalledWith('pty-recycled', {
tabId: 'tab-old'
})
)
store.upsertSshRemotePtyLease({
targetId: 'target-1',
ptyId: 'ssh:target-1@@relay-current@@pty-recycled',
tabId: 'tab-new',
state: 'detached'
})
resolveAttach({ replay: 'stale-output' })
await establishing
expect(store.getSshRemotePtyLeases('target-1')).toEqual([
expect.objectContaining({
ptyId: 'pty-recycled',
relayInstanceId: 'relay-current',
tabId: 'tab-new',
state: 'detached'
})
])
expect(setPtyOwnership).not.toHaveBeenCalledWith(
'ssh:target-1@@relay-current@@pty-recycled',
'target-1'
)
expect(mockWindow.webContents.send).not.toHaveBeenCalledWith('pty:replay', {
id: 'ssh:target-1@@relay-current@@pty-recycled',
data: 'stale-output'
})
} finally {
store.flush()
rmSync(dir, { recursive: true, force: true })
}
})
it('expires a failed legacy identity without adopting the current relay generation', async () => {
const dir = mkdtempSync(join(tmpdir(), 'orca-stale-ssh-lease-'))
const store = new Store({ dataFile: join(dir, 'state.json') })
+1 -1
View File
@@ -1286,7 +1286,7 @@ export class SshRelaySession {
ptyId,
relayInstanceId
)
if (!migrated && !this.store.markSshRemotePtyLease(this.targetId, appPtyId, 'attached')) {
if (!migrated) {
continue
}
} else {