mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 10:27:33 +00:00
relay-edge: reconnect_gap metric (time from a host's last control close to its next activation) (#41034)
Diagnostics only. Separates sleeping hosts (long gap) from awake hosts whose connection was dropped (short gap) after silence closes. Stores one small per-host key, cleared on the next activation and by erase.
This commit is contained in:
@@ -77,6 +77,9 @@ export const NO_DEADLINE = Number.MAX_SAFE_INTEGER
|
||||
// How long a silent keepalive control has to answer the relay ping before it is closed.
|
||||
export const KEEPALIVE_PROBE_MS = 10_000
|
||||
export const SWEEP_AT_KEY = 'sweepAt'
|
||||
// Diagnostics only: the host's last control close, read once by the next activation.
|
||||
export const LAST_CONTROL_CLOSE_KEY = 'lastControlClose'
|
||||
export type LastControlClose = { goneAt: number; closedAt: number; code: number }
|
||||
// 6 h ± 30 min, as the cells: desktops re-ask the director at least this often.
|
||||
export const LEASE_BASE_MS = 6 * 60 * 60 * 1000
|
||||
export const LEASE_JITTER_MS = 30 * 60 * 1000
|
||||
@@ -181,6 +184,7 @@ export abstract class HostRelayBase extends DurableObject<Env> {
|
||||
this.attach(ws, null)
|
||||
if (a.k === 'control' && a.phase === 'active') { metric(this.env, 'control_close', 1, String(code), [], '', a.place) }
|
||||
if (a.k === 'control' && a.phase === 'active' && !this.activeControl()) {
|
||||
await this.ctx.storage.put<LastControlClose>(LAST_CONTROL_CLOSE_KEY, { goneAt, closedAt: Date.now(), code })
|
||||
const session = await this.ctx.storage.get<Session>('session')
|
||||
if (session && session.generation === a.generation) {
|
||||
const hostReason = relayHostCloseReasonFrom(reason)
|
||||
|
||||
@@ -7,7 +7,7 @@ import { RELAY_CLOSE_CODE } from '../../../packages/relay-contract/src/close-cod
|
||||
import { metric } from './metrics'
|
||||
import type { EdgeClaims } from './env'
|
||||
import { b64, b64url, fromB64, hmacSha256, sha256B64url, timingSafeEqualStr } from './bytes'
|
||||
import { HostRelayBase, ASSIGNMENT_CHECK_DEADLINE_MS, NO_DEADLINE, LEASE_BASE_MS, LEASE_JITTER_MS, type ControlAttachment, type Session } from './host-relay-base'
|
||||
import { HostRelayBase, ASSIGNMENT_CHECK_DEADLINE_MS, NO_DEADLINE, LEASE_BASE_MS, LEASE_JITTER_MS, type ControlAttachment, type Session, LAST_CONTROL_CLOSE_KEY, type LastControlClose } from './host-relay-base'
|
||||
|
||||
export abstract class HostRelayHandshake extends HostRelayBase {
|
||||
protected async onHostHello(ws: WebSocket, a: ControlAttachment, type: unknown, body: Record<string, unknown>): Promise<void> {
|
||||
@@ -193,6 +193,11 @@ export abstract class HostRelayHandshake extends HostRelayBase {
|
||||
// After the ack, which strict shipped parsers must see unchanged; only hosts that asked get it.
|
||||
if (a.clientKeepalive) { this.send(ws, { type: 'keepalive-offer', v: 1, intervalMs: this.config.pingIntervalMs }) }
|
||||
metric(this.env, 'control_active', 1, rebind ? 'rebind' : 'new', [a.openedAt === undefined ? -1 : now - a.openedAt], a.clientKeepalive ? 'keepalive' : 'legacy', a.place)
|
||||
const last = await this.ctx.storage.get<LastControlClose>(LAST_CONTROL_CLOSE_KEY)
|
||||
if (last) {
|
||||
await this.ctx.storage.delete(LAST_CONTROL_CLOSE_KEY)
|
||||
metric(this.env, 'reconnect_gap', Math.round((now - last.goneAt) / 1000), String(last.code), [Math.round((last.closedAt - last.goneAt) / 1000)], a.clientKeepalive ? 'keepalive' : 'legacy', a.place)
|
||||
}
|
||||
await this.reschedule()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,11 @@ export type MetricEvent =
|
||||
| 'auth_expired_close'
|
||||
// Control closed for silence (deadControlMetric, host-relay-control.ts).
|
||||
| 'silence_close'
|
||||
// A host's control came back after its last control closed: value = seconds from when that
|
||||
// control was last known alive (silence closes) or closed (others) to this activation; label =
|
||||
// that close code; double2 = seconds between last-known-alive and the actual close.
|
||||
// reason 'keepalive' | 'legacy' of the new control.
|
||||
| 'reconnect_gap'
|
||||
// Pre-auth socket refused by the per-source limiter: label 'phone' | 'data' | 'health'. Unpushed-host phones: 'not_on_edge'.
|
||||
| 'preauth_limited'
|
||||
| 'not_on_edge'
|
||||
|
||||
Reference in New Issue
Block a user