Keep managed servers unverifiable until they answer (#26637)

* Require a server reply before treating a live managed process as serving

* Log the unanswered live managed server like the other unverifiable verdicts

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
Co-authored-by: OrcaWin <alpha-eng@stably.ai>
This commit is contained in:
Neil
2026-10-09 04:22:17 -07:00
committed by GitHub
co-authored by m4air OrcaWin
parent c12c211804
commit 3bcb312043
5 changed files with 92 additions and 3 deletions
+23 -1
View File
@@ -84,7 +84,29 @@ describe('ensureManagedOrcadServing', () => {
it('leaves a live process that did not answer alone', async () => {
vi.mocked(wakeStoppedManagedOrcad).mockResolvedValue({ outcome: 'serving' })
expect(await ensureManagedOrcadServing(input(async () => false))).toEqual({ state: 'serving' })
const serving = await ensureManagedOrcadServing(input(async () => false))
expect(serving).toMatchObject({ state: 'unverifiable' })
expect(listener.starting).not.toHaveBeenCalled()
})
it('accepts a live process once a fresh probe answers after the host check', async () => {
vi.mocked(wakeStoppedManagedOrcad).mockResolvedValue({ outcome: 'serving' })
const probe = vi.fn(async () => true).mockResolvedValueOnce(false)
expect(await ensureManagedOrcadServing(input(probe))).toEqual({ state: 'serving' })
expect(probe).toHaveBeenCalledTimes(2)
expect(listener.starting).not.toHaveBeenCalled()
})
it('keeps a failed fresh probe unverifiable without starting another process', async () => {
vi.mocked(wakeStoppedManagedOrcad).mockResolvedValue({ outcome: 'serving' })
const probe = vi
.fn(async () => false)
.mockResolvedValueOnce(false)
.mockRejectedValueOnce(new Error('SSH link was replaced'))
expect(await ensureManagedOrcadServing(input(probe))).toEqual({
state: 'unverifiable',
detail: 'SSH link was replaced'
})
expect(listener.starting).not.toHaveBeenCalled()
})
+7 -1
View File
@@ -137,7 +137,13 @@ async function wakeIfStopped(
}
// A live process that did not answer may still be starting; it is not restarted.
if (wake.outcome === 'serving') {
return { state: 'serving' }
// Why: a live PID proves the process exists, not that it answers.
if (await input.probe(input.environment, PROBE_TIMEOUT_MS)) {
return { state: 'serving' }
}
const detail = 'The managed Orca server process is live but is not answering.'
console.warn(`[ssh] The managed Orca server on ${label} is not answering: ${detail}`)
return { state: 'unverifiable', detail }
}
const detail = wakeRefusal(wake.outcome)
console.warn(`[ssh] The managed Orca server on ${label} is not answering: ${detail}`)