Found by adversarial audit @ 261d00b, survived refutation WITH empirical probes (conf 0.85).
Mechanism: isRedisHealthy races PING against a hard 2000ms timer and marks lastPingOk=false on any single timeout/error (src/redis.ts:14,59-70); only a <2s ping restores it. Under load where Redis answers correctly in 2-5s, every watchdog tick fails, the ≥15s streak triggers reinitRedis (src/index.ts:117-127) which closes the old client — measured Bun 1.3.14 rejects ALL pending commands (ERR_REDIS_CONNECTION_CLOSED) — then swaps clients whose probes also time out → cycle repeats ~every 20s with no backoff until latency drops below 2s. A CLIENT PAUSE probe showed the untouched old client recovers by itself; the intervention only destroys working state. (Corrections to original claim: null-client window is unobservable — sync handoff into initRedis; post-swap requests ride the offline queue and drain well inside the 30s budget.)
Fix direction: distinguish 'disconnected/wedged' (client.connected === false, onclose fired, retries exhausted) from 'slow' (probe timeout with connected === true) and reinit only for the former; alternatively require N consecutive failures with threshold nearer connectionTimeout than PING_TIMEOUT.
Found by adversarial audit @ 261d00b, survived refutation WITH empirical probes (conf 0.85).
Mechanism: isRedisHealthy races PING against a hard 2000ms timer and marks lastPingOk=false on any single timeout/error (src/redis.ts:14,59-70); only a <2s ping restores it. Under load where Redis answers correctly in 2-5s, every watchdog tick fails, the ≥15s streak triggers reinitRedis (src/index.ts:117-127) which closes the old client — measured Bun 1.3.14 rejects ALL pending commands (ERR_REDIS_CONNECTION_CLOSED) — then swaps clients whose probes also time out → cycle repeats ~every 20s with no backoff until latency drops below 2s. A CLIENT PAUSE probe showed the untouched old client recovers by itself; the intervention only destroys working state. (Corrections to original claim: null-client window is unobservable — sync handoff into initRedis; post-swap requests ride the offline queue and drain well inside the 30s budget.)
Fix direction: distinguish 'disconnected/wedged' (client.connected === false, onclose fired, retries exhausted) from 'slow' (probe timeout with connected === true) and reinit only for the former; alternatively require N consecutive failures with threshold nearer connectionTimeout than PING_TIMEOUT.