mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
fix(ssh): a Disconnect or Remove during a background connect sticks (#29918)
A background connect (managed tunnel, census, runtime context) that was waiting for the old transport to close resumed after the user's Disconnect or Remove host and registered a fresh connection. Re-check the attempt token after that await so the cancelled attempt never registers.
This commit is contained in:
@@ -169,6 +169,30 @@ describe('SshConnectionManager', () => {
|
||||
expect(manager.getConnection(target.id)).toBe(replacement)
|
||||
})
|
||||
|
||||
it('keeps a Disconnect that lands while a background connect closes the old transport', async () => {
|
||||
const manager = new SshConnectionManager({ onStateChange: vi.fn() })
|
||||
await manager.connect(target)
|
||||
const old = mockState.instances[0]
|
||||
// The pooled transport dropped, so a background dial (tunnel, census) replaces it.
|
||||
old.status = 'disconnected'
|
||||
let finishOldClose!: () => void
|
||||
old.disconnect.mockImplementationOnce(
|
||||
() =>
|
||||
new Promise<void>((resolve) => {
|
||||
finishOldClose = resolve
|
||||
})
|
||||
)
|
||||
|
||||
const background = manager.connect(target)
|
||||
const rejected = expect(background).rejects.toThrow('cancelled')
|
||||
await manager.disconnect(target.id)
|
||||
finishOldClose()
|
||||
await rejected
|
||||
|
||||
expect(mockState.instances).toHaveLength(1)
|
||||
expect(manager.getConnection(target.id)).toBeUndefined()
|
||||
})
|
||||
|
||||
it('leaves a connection whose own reconnect is asking the user alone', async () => {
|
||||
const manager = new SshConnectionManager({ onStateChange: vi.fn() })
|
||||
const conn = await manager.connect(target)
|
||||
|
||||
@@ -63,6 +63,11 @@ export class SshConnectionManager {
|
||||
if (existing) {
|
||||
this.retainSignIn(target.id, existing)
|
||||
await existing.disconnect()
|
||||
// Why: a Disconnect or Remove while the old transport closed cancels this attempt;
|
||||
// registering now would revive the host the user just let go.
|
||||
if (this.connectingTargets.get(target.id) !== attempt) {
|
||||
throw new Error(`Connection to ${target.label} was cancelled`)
|
||||
}
|
||||
}
|
||||
|
||||
const conn = new SshConnection(target, this.callbacks, this.takeRetainedSignIn(target))
|
||||
|
||||
Reference in New Issue
Block a user