Repository navigation
fix(realtime): end a failed socket-token attempt promptly and honor Retry-After - #8952
Conversation
The Socket.IO auth callback never invoked cb when POST /api/auth/socket-token
failed (429, 5xx, network), so the open transport sat until the realtime
server's 45 s connectTimeout while the UI showed Reconnecting, and Retry-After
was ignored. The client `timeout` cannot help: the Manager clears it when the
transport opens, and resets its backoff on every open, so each retry ran at
the 1 s floor.
On a retryable mint failure, disconnect the socket and reconnect it on the
existing auth backoff (1 s to 30 s, matching the reconnection config), never
before the response's Retry-After. 401 keeps its cb({ token: null }) path.
…retry disconnect() on a socket that has not connected yet emits no 'disconnect' event. After a native reconnect is followed by a failed token mint, isConnected stayed true for the whole outage. Clear it, and the socket id, exactly as the 'disconnect' handler does. Spread a Retry-After-driven delay by up to +20% above the floor, so tabs behind one IP do not retry in the same second.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
There was a problem hiding this comment.
No issues found across 1 file
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Heads up: you’ve reached your flex budget. Increase your flex budget or wait for usage to reset.
Turn on auto-fix | Re-trigger cubic
|
…report persistent token outages
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
No issues found across 1 file
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Heads up: you’ve reached your flex budget. Increase your flex budget or wait for usage to reset.
Turn on auto-fix | Re-trigger cubic
Summary
When the realtime socket's
authcallback can't get a token from/api/auth/socket-token(a 429 from its 30/min per-IP limit, a network error, or a 5xx), it never calledcb. socket.io-client 4.8.1 sends CONNECT only from insidecb(socket.js:407-423), and the client's own 10s timeout is cleared once the transport opens (manager.js:135-170). So the attempt sat open until the realtime server's default 45s connect timeout, and users saw "Reconnecting…" the whole time.Retry-Afterwas ignored.Just ending the attempt early isn't enough. The Manager resets its backoff on every transport open (
manager.js:306, 361-365), so it would retry about once a second forever.The fix, for any failure other than 401:
disconnecthandler does. Without that, a reconnect followed by an auth failure would keep showing "connected".backoffWithJitter(1s growing to 30s, the existing auth-retry constants). When the server sentRetry-After(parsed withparseRetryAfter, capped at 5 min because the route's bucket refills over 60s), wait at least that long, plus up to 20% jitter so tabs behind one IP don't retry in the same second.!activeguard means nothing gets scheduled.connect.The 401 path (session gone, passes a null token, goes terminal) is unchanged. No server or rate-limit changes.
Effect: "Reconnecting…" appears after the existing 2s anti-flicker delay instead of about 45s, and the socket reconnects as soon as the backoff or
Retry-Afterallows. During a long token-route outage, each tab retries about every 30s, compared with about every 46s before.Verified against a real Socket.IO server with a script: the old code hangs; the new code ends the attempt promptly, waits the delay, then connects; a 401 still produces
connect_errorwithactive=false. An adversarial review checked re-entrancy, timer races, unmount and sign-out, and backoff resets. Its two findings, the staleisConnectedand the jitter, are included here.Test plan
e2e (mobile, *): the socket-token mint check still passes