mirror of
https://github.com/stablyai/orca.git
synced 2026-10-23 16:03:49 +00:00
fix(ssh): report process exit again on relays that send no incarnation id
A host exit notification is positive evidence of death; a missing incarnation id only means we cannot attribute it. Treating every incarnation-less exit as ambiguous meant that against an older relay — one that never sends the field — panes never showed "Process exited" and the lease never reached 'terminated'. Mixed client/host versions are the normal state, so restore delivery when no incarnation was recorded, and keep the fence only where one was.
This commit is contained in:
@@ -79,7 +79,13 @@ vi.mock('../providers/ssh-pty-provider', () => ({
|
||||
this.pendingLiveEvidence.clear()
|
||||
})
|
||||
acceptAmbiguousExitPty = vi.fn((id: string) => this.acceptUnverifiablePty(id))
|
||||
acceptExitedPtyLiveness = vi.fn()
|
||||
// Mirrors SshPtyLivenessState.acceptExited, which invalidates pending live evidence.
|
||||
acceptExitedPtyLiveness = vi.fn((_id: string) => {
|
||||
for (const evidence of this.pendingLiveEvidence) {
|
||||
evidence.valid = false
|
||||
}
|
||||
this.pendingLiveEvidence.clear()
|
||||
})
|
||||
acceptExitedPty = vi.fn()
|
||||
dispose = vi.fn()
|
||||
|
||||
@@ -307,7 +313,7 @@ describe('SSH relay PTY incarnation exits', () => {
|
||||
onData: ReturnType<typeof vi.fn>
|
||||
onExit: ReturnType<typeof vi.fn>
|
||||
acceptLivePty: ReturnType<typeof vi.fn>
|
||||
acceptAmbiguousExitPty: ReturnType<typeof vi.fn>
|
||||
acceptExitedPtyLiveness: ReturnType<typeof vi.fn>
|
||||
settleLivePtyEvidence: ReturnType<typeof vi.fn>
|
||||
}
|
||||
vi.mocked(getSshPtyProvider).mockReturnValue(provider as never)
|
||||
@@ -340,7 +346,7 @@ describe('SSH relay PTY incarnation exits', () => {
|
||||
settleOutput()
|
||||
|
||||
await vi.waitFor(() => expect(provider.settleLivePtyEvidence).toHaveBeenCalledOnce())
|
||||
expect(provider.acceptAmbiguousExitPty).toHaveBeenCalledExactlyOnceWith(id)
|
||||
expect(provider.acceptExitedPtyLiveness).toHaveBeenCalledExactlyOnceWith(id)
|
||||
expect(provider.acceptLivePty).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
@@ -373,7 +379,7 @@ describe('SSH relay PTY incarnation exits', () => {
|
||||
expect(acceptOutputExitMock).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('marks a legacy exit unverifiable without incarnation ownership', async () => {
|
||||
it('delivers an exit from a relay that never sends an incarnation', async () => {
|
||||
const { mockConn, mockStore, mockPortForward, getMainWindow } = createMockDeps()
|
||||
const session = new SshRelaySession('target-1', getMainWindow, mockStore, mockPortForward)
|
||||
await session.establish(mockConn)
|
||||
@@ -388,16 +394,22 @@ describe('SSH relay PTY incarnation exits', () => {
|
||||
ptyIncarnation: string
|
||||
}) => void
|
||||
|
||||
// No incarnation was ever recorded for this PTY, so isCurrentPtyExit admits the exit.
|
||||
onExit({
|
||||
id: 'ssh:target-1@@pty-legacy',
|
||||
code: 0,
|
||||
code: 3,
|
||||
providerGeneration: 31,
|
||||
ptyIncarnation: 'legacy:31:1:pty-legacy'
|
||||
})
|
||||
|
||||
expect(provider.acceptAmbiguousExitPty).toHaveBeenCalledExactlyOnceWith(
|
||||
'ssh:target-1@@pty-legacy'
|
||||
await vi.waitFor(() =>
|
||||
expect(acceptOutputExitMock).toHaveBeenCalledWith({
|
||||
id: 'ssh:target-1@@pty-legacy',
|
||||
code: 3,
|
||||
providerGeneration: 31,
|
||||
ptyIncarnation: 'legacy:31:1:pty-legacy'
|
||||
})
|
||||
)
|
||||
expect(acceptOutputExitMock).not.toHaveBeenCalled()
|
||||
expect(provider.acceptAmbiguousExitPty).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1785,11 +1785,12 @@ export class SshRelaySession {
|
||||
this.wakeRecovery(pendingReattach)
|
||||
return
|
||||
}
|
||||
if (!payload.incarnationId) {
|
||||
ptyProvider.acceptAmbiguousExitPty(payload.id)
|
||||
return
|
||||
}
|
||||
if (!isCurrentPtyExit(payload)) {
|
||||
// Why: an exit we cannot attribute to the recorded incarnation is not proof THIS PTY died.
|
||||
// A relay that never sends incarnations records none, so its exits still deliver.
|
||||
if (!payload.incarnationId) {
|
||||
ptyProvider.acceptAmbiguousExitPty(payload.id)
|
||||
}
|
||||
return
|
||||
}
|
||||
void this.acceptPtyExit(payload).catch(() => {})
|
||||
|
||||
Reference in New Issue
Block a user