Frontend reconnect hardening: tab wake & reconnect probe - #172
Conversation
handleBroken published a fresh stub every backoff cycle before it had round-tripped: capnweb queues sends while the socket is CONNECTING, so the unproven stub looked fine until every effect pipelined onto it failed at once, once per cycle. And because useAuth pipelines authenticate() without awaiting, markConnectionRestored() fired instantly and the Reconnecting chip flickered off/on all outage long. Rework handleBroken into a recovery loop that probes each candidate with getServerConfig() (20s timeout) and only publishes it once the probe round-trips. During the outage the published stub stays the dead one, so stub-keyed effects don't re-fire per attempt; subscribers hear exactly twice per outage — lost, then restored. The proof replaces markConnectionRestored(), so delete it and its __root.tsx effect. Keeps today's fast recovery from one-off blips: the first backoff is skipped when the dying connection had been up longer than the initial backoff. The workspace editor's Reconnecting chip previously appeared only as a side effect of the churn: each republish re-fired the workspace-open effect, whose failure set the workspace-level connectionLost. With the dead stub staying published, drive the chip from the socket-level flag too.
Nothing detected a socket killed during laptop sleep or background tab throttling: the user woke the tab and their first action hung on a zombie socket before recovery even started. On tab-visible and network-online signals, probe currentStub with getServerConfig() under a 10s timeout — skipped while reconnecting, while a probe is already in flight, or when the connection was proven alive within the last 15s (so rapid tab switches stay silent). On timeout, dispose the stub; that fires onRpcBroken and the recovery loop takes over, whose skip-first-backoff path retries immediately — right for "the network just came back".
|
Now let me assess one final real concern: the Let me double-check the jitter/backoff produces the PR's claimed measurements to validate correctness of the loop, and confirm Trace: server down, connection was up > 1s → But there's a subtle issue: if I've completed a thorough review. My findings are minor/low-confidence; none are clear defects introduced by the change. Let me summarize. Overall this is a well-constructed change. Let me note the observations I have. Review SummaryThis is a solid, well-reasoned change. The design correctly separates the two concerns (socket-level RPC state via I found no clear defects introduced by this change. A few low-confidence observations (none blocking):
The removed LGTM! |
|
|
Hmm, it looks like Cap'n Web actually might not currently expose a way to construct an RpcPromise/RpcStub from a Promise (or generally a Promise). We should probably add that. In raw Cap'n Proto we use it all the time. Either |
I actually have a branch that does exactly this: let me see if I can get it over the line |
Handles 2 cases the server cannot automagically help with recovery on:
getServerConfig()and only publish a stub that has round-tripped. This stops false reporting a reconnected state just to go back to disconnectedvisibilitychange/onlinetriggers a probe of the current stubTesting
Types, unit tests, lint. Manually against the local dev stack: