mirror of
https://github.com/NeuralNomadsAI/CodeNomad.git
synced 2026-07-10 00:14:27 +00:00
## Problem
When the client receives a ping from the server, it responds with a pong
via HTTP POST. On unstable networks (mobile, WiFi with poor signal,
network switches), this POST can fail in multiple ways:
- **Hung requests**: `fetch()` never rejects, blocking retries
indefinitely
- **Network disconnection**: `Failed to fetch`
- **Brief disconnections**: transient network errors
Previously, a single missed pong would cause the server to close the SSE
connection after 45s, leaving message responses stuck in queue until the
next message triggered a reconnection.
## Solution
Three improvements to make the pong POST resilient:
### 1. Request timeout (10s)
Each pong POST is now bounded with a 10s `AbortSignal` timeout. Hung
requests fail fast instead of blocking indefinitely, allowing retries to
start before the server's stale connection sweep.
### 2. Selective retry with `isRetryableError()`
Only retries transient failures where recovery is possible:
- `AbortError` / `TimeoutError` (hung or timed-out requests)
- `Failed to fetch` (network disconnected)
- `NetworkError` (browser network errors)
Non-retryable errors like `404 Client connection not found` (permanently
closed connection) fail immediately instead of wasting retry attempts.
### 3. Exponential backoff (3 attempts, 100ms → 2000ms)
Handles burst failures gracefully without hammering the server.
## Changes
- **`packages/ui/src/lib/retry-utils.ts`** (new): Reusable retry utility
with `timeoutMs` and `shouldRetry` predicate support
- **`packages/ui/src/lib/server-events.ts`**: Updated pong handler to
use bounded timeout + selective retry
## Verification
- Build passes: `npm run build:ui` ✅
- Manually verified in production logs: retries now visible as `Pong
failed after retries` instead of single immediate failure
- SSE monitor log at `~/.codenomad/logs/sse-monitor.log` shows `PONG_OK`
/ `PONG_FAIL` / `STALE` events for ongoing monitoring
|
||
|---|---|---|
| .. | ||
| cloudflare | ||
| electron-app | ||
| opencode-plugin | ||
| server | ||
| tauri-app | ||
| ui | ||