Repository navigation
fix(client-runtime): foreground retries every 15 s and phones keep a connection log - #193
Merged
Merged
Conversation
…connection log A phone that lost its path (server-side client-silent reset) could back off for minutes while the user was looking at it. Foregrounded clients now cap backoff at 15 s. Each environment keeps its last 50 connection events, viewable and copyable in mobile Settings, and failures ride the next activity report so the server log shows what the phone saw. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
JJ's phone connects after a Tailscale reset, drops about 30 s later, then shows "reconnecting" for minutes. The server logs show the phone's path dying, not the app stalling. This PR keeps a foregrounded app retrying at least every 15 s, and gives the phone a connection log so the next failure explains itself.
Evidence (2026-11-04)
client-silentat 16:44:03.8. Every phone socket that day (11:42, 11:44, 11:46, 15:27, 16:44) ended the same way. 0send-stalled.send-stalled, 9client-silent, all from mobile. The 16:42:10 socket ended after 103 s as Interrupted.tailscale pingworked again at ~17:03 (46 ms).What each hypothesis does now
AppStateon mobile,visibilityStateon web/desktop). Backgrounded clients keep the existing exponential backoff, so a pocketed phone doesn't drain the battery. TestClock test: 40×15 s foregrounded gives ≥30 attempts (fails at 9 without the cap); backgrounded gives <10 in 10 min.ws.close, and fetches abort on interrupt. I found no path that hangs.Connection: close(and it's illegal in h2), and a unique URL still reuses the per-origin pool. The WebSocket (SocketRocket) opens a fresh TCP connection every attempt, and route checks already usecache: "no-store". A code comment bycheckDescriptorrecords this.wsClientLiveness.tsalone for fix(client-runtime): restore fork connection fixes lost in upstream syncs #192 to own. This PR doesn't touch fix(client-runtime): ride out packet-loss bursts on mobile tailnet connections #106's probe/ping timeouts or fix(client-runtime): a dropped session request no longer locks the composer #150's session retry.Diagnostics
client-runtimekeeps a per-environment log of the last 50 transitions (attempt / connected / failed / lost / waiting), each with route, stage, reason, detail (≤160 chars), network, and fg/bg.connectionTrouble, optional, schema-capped). The server logs them asclient reported connection troubleand doesn't store them.Surfaces
Checks
vp run check:changed: format, lint, knip, tests, and react compiler pass. Its typecheck step can't spawn in this sandbox (seccompSUN_LEN), so I rantsc --noEmitdirectly in client-runtime, contracts, mobile, web, server, and desktop: clean.lint:mobileonly runs native checks, and ktlint/swiftlint aren't installed here; no native code changed.Shipping: JJ's iOS build has OTA disabled, so this needs a new TestFlight build.
Opus 5.5 via Claude Code in T3 Code.
🤖 Generated with Claude Code