mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-13 21:27:41 +02:00
[eric] resilience: a stalled request probes the backend instead of waiting out its timeout, so a wedged port surfaces in seconds
This commit is contained in:
@@ -62,5 +62,22 @@ export function noteBackendSuccess(): void {
|
||||
}
|
||||
}
|
||||
|
||||
// A request that STALLS (a squatted or wedged port accepts the connection and never answers) would
|
||||
// otherwise take the full attempt timeout before counting as a failure, leaving the user staring at
|
||||
// a spinner for ~25s+ with the signal still green. The stall watchdog asks the prober directly, so
|
||||
// "is the backend actually alive" is answered in seconds regardless of how long the request hangs.
|
||||
export function probeNow(): void {
|
||||
if (!prober) return;
|
||||
void prober().then(() => noteBackendSuccess()).catch(() => noteBackendFailure());
|
||||
}
|
||||
|
||||
export function noteRequestStalled(): void {
|
||||
if (!reachableNow) return;
|
||||
probeNow();
|
||||
// Two probe failures are what flips the signal, matching the normal path; a backend that answers
|
||||
// either probe is simply slow, not down, and nothing is shown.
|
||||
setTimeout(() => { if (reachableNow) probeNow(); }, 1200);
|
||||
}
|
||||
|
||||
// Harness/debug handle: lets a live session (CDP, support) read the signal without a store import.
|
||||
(window as unknown as { __OSW_CONN?: object }).__OSW_CONN = { backendReachable, onBackendReachability };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { noteBackendFailure, noteBackendSuccess, setBackendProber } from '@/shared/backendConnection';
|
||||
import { noteBackendFailure, noteBackendSuccess, noteRequestStalled, setBackendProber } from '@/shared/backendConnection';
|
||||
|
||||
const _w = window as any;
|
||||
// Prefer the preload-injected port; if it's missing (preload raced the backend port being picked), re-query the live value before falling back to 8324. The bare 8324 guess is wrong on any machine where the backend landed on a fallback port (e.g. 8324 was held by a leftover backend); see the self-heal below.
|
||||
@@ -104,6 +104,14 @@ function _installAuthFetchInterceptor() {
|
||||
return { ...(finalInit ?? {}), signal: callerSignal ? AbortSignal.any([callerSignal, timeout]) : timeout };
|
||||
};
|
||||
|
||||
// Anything on loopback that hasn't answered in 8s is stalled, not slow; ask the prober rather than
|
||||
// waiting out the attempt timeout, so a squatted/wedged port surfaces in seconds (ENG-242).
|
||||
const STALL_MS = 8000;
|
||||
const withStallWatch = async (run: () => Promise<Response>): Promise<Response> => {
|
||||
const stall = setTimeout(() => noteRequestStalled(), STALL_MS);
|
||||
try { return await run(); } finally { clearTimeout(stall); }
|
||||
};
|
||||
|
||||
window.fetch = async function patchedFetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
|
||||
try {
|
||||
const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : (input as Request).url;
|
||||
@@ -131,7 +139,7 @@ function _installAuthFetchInterceptor() {
|
||||
// legitimately slow); they still feed the reachability signal so the UI stays honest.
|
||||
if (method !== 'GET') {
|
||||
try {
|
||||
const resp = await originalFetch(input, finalInit);
|
||||
const resp = await withStallWatch(() => originalFetch(input, finalInit));
|
||||
noteBackendSuccess();
|
||||
return resp;
|
||||
} catch (err) {
|
||||
@@ -163,7 +171,7 @@ function _installAuthFetchInterceptor() {
|
||||
let lastErr: unknown = null;
|
||||
for (let attempt = 0; attempt <= GET_RETRY_DELAYS_MS.length; attempt++) {
|
||||
try {
|
||||
const resp = await originalFetch(input, attemptInit(finalInit));
|
||||
const resp = await withStallWatch(() => originalFetch(input, attemptInit(finalInit)));
|
||||
if (isTransientStatus(resp.status) && attempt < GET_RETRY_DELAYS_MS.length) {
|
||||
await new Promise((r) => setTimeout(r, GET_RETRY_DELAYS_MS[attempt]));
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user