Commit 6ecf1d7
committed
feat(sdk): resilient SSE reconnection in chat transport
Replace the legacy 5-attempt retry cap on SSEStreamSubscription with
indefinite retry on a bounded jittered backoff. Adds a force-reconnect
path so the chat transport can recover from silent-dead-socket cases
on mobile (background-kill, bfcache restore) without waiting for the
next backoff slot.
SSEStreamSubscription:
- maxRetries default Infinity (was 5), retryDelayMs 100ms (was 1s),
new maxRetryDelayMs cap (5s), retryJitter 50%
- retryNow(): wake an in-flight backoff
- forceReconnect(): drop current connection AND wake backoff
- fetchTimeoutMs (30s default): aborts stuck connect attempts that
block forever on dead sockets
- stallTimeoutMs (opt-in): force reconnect on silent reader
- nonRetryableStatuses (default [404, 410]): short-circuit retry
for stream-gone / session-closed
- Fixed listener leak where each retry accumulated an abort listener
on the user signal because finally only ran once the recursion
unwound. Cleanup now runs per-attempt via cleanupAttempt() in both
the catch (before recursion) and finally paths.
TriggerChatTransport (browser):
- online -> forceReconnect (existing socket may be stale)
- pageshow.persisted -> forceReconnect (Safari bfcache restore)
- visibilitychange -> visible only:
* hidden >= 30s -> forceReconnect
* hidden < 30s -> retryNow (cheap wake)
- stallTimeoutMs: 60s (sized over typical agent thinking pauses)
Tests: 13 vitest cases covering retry-past-legacy-cap, backoff cap,
jitter variance, retryNow short-circuit, abort-during-backoff,
forceReconnect during fetch and during read (verifies Last-Event-ID
resume on the resumed request), fetchTimeout, stallTimeout, 404/410
short-circuit, custom nonRetryableStatuses, 503 still retries.
Refs TRI-8903.1 parent 75cf364 commit 6ecf1d7
3 files changed
Lines changed: 662 additions & 31 deletions
0 commit comments