mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 08:02:28 +00:00
fix(web): declare a socket dead even when its probe cannot be sent (#17838)
* fix(web): declare a socket dead even when its probe cannot be sent * chore: land the shared liveness policy with its first real adopter instead * docs: drop the reference to a file this PR no longer adds
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { WebRuntimeConnectionHeartbeat } from './web-runtime-connection-heartbeat'
|
||||
|
||||
// A probe that cannot be written is the strongest evidence the link is gone. Gating the deadline on
|
||||
// a successful send disarms the only branch that can declare the socket dead, so a saturated or
|
||||
// half-open socket is never judged at all — the wedge fixed on the SSH transport in #17817.
|
||||
describe('WebRuntimeConnectionHeartbeat when the probe cannot be sent', () => {
|
||||
it('still declares the socket dead instead of watching it forever', () => {
|
||||
let now = 0
|
||||
const socket = { readyState: 1, close: vi.fn() } as unknown as WebSocket
|
||||
const handleDeadSocket = vi.fn()
|
||||
const heartbeat = new WebRuntimeConnectionHeartbeat({
|
||||
now: () => now,
|
||||
isDocumentVisible: () => true,
|
||||
isConnected: () => true,
|
||||
getSocket: () => socket,
|
||||
// The saturated / half-open case: the send never leaves.
|
||||
sendProbe: () => false,
|
||||
handleDeadSocket
|
||||
})
|
||||
|
||||
heartbeat.lastInboundFrameAt = 0
|
||||
heartbeat.lastHeartbeatTickAt = 0
|
||||
for (const tickAt of [10_000, 20_000, 30_000, 40_000, 50_000]) {
|
||||
now = tickAt
|
||||
heartbeat.runTick()
|
||||
}
|
||||
|
||||
expect(handleDeadSocket).toHaveBeenCalledWith(socket)
|
||||
})
|
||||
})
|
||||
@@ -69,9 +69,13 @@ export class WebRuntimeConnectionHeartbeat {
|
||||
return
|
||||
}
|
||||
if (this.heartbeatProbeSentAt === null && now - this.lastInboundFrameAt >= HEARTBEAT_IDLE_MS) {
|
||||
if (this.options.sendProbe()) {
|
||||
this.heartbeatProbeSentAt = now
|
||||
}
|
||||
// Why the deadline is armed before the send and regardless of its result: a probe that could
|
||||
// not be written is the strongest evidence the link is gone, not a reason to stop watching.
|
||||
// Gating this on a successful send disarms the only branch above that can declare the socket
|
||||
// dead, so a saturated or half-open socket would never be judged at all -- the same wedge
|
||||
// fixed on the SSH transport in #17817. See also #17823.
|
||||
this.heartbeatProbeSentAt = now
|
||||
this.options.sendProbe()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user