authorgravatar for me@t3.ggTheo Browne <me@t3.gg> 2026-09-25 20:28:35-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-25 20:28:35-07:00
logb2577d6eface9589d120bdc53e4ec0431b1e9331
tree5f3e0ba189380ac58b62c85aaf1ff5bc131e3ff0
parentb6eefc926ae305f4cb85cca797668b010cee1136
signature Signed by PGP key B5690EEEBB952194

fix(client): slow servers finish loading the thread list instead of loading it twice (#13683)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

3 files changed, 16 insertions(+), 9 deletions(-)

packages/client-runtime/src/state/session.ts+2-2
......@@ -30,8 +30,8 @@ function initialConfigOption<E>(
3030 );
3131}
3232
33// Bounded like the snapshot fetches: a wedged environment must not pin the
34// permissions check (and with it the settings UI) in a loading state for long.
33// Bounded so a wedged environment cannot pin the permissions check (and with it
34// the settings UI) in a loading state for long.
3535const DEFAULT_SESSION_STATE_TIMEOUT_MS = 6_000;
3636
3737/**
packages/client-runtime/src/state/shellSnapshotHttp.ts+7-3
......@@ -12,9 +12,13 @@ import { environmentEndpointUrl } from "../environment/endpoint.ts";
1212import { ManagedRelayDpopSigner } from "../relay/managedRelay.ts";
1313import { executeAuthenticatedEnvironmentHttpRequest } from "./environmentHttpAuth.ts";
1414
15// Bounded so a pathologically slow endpoint cannot block the (cheaper) socket
16// fallback for long. The cached shell renders while this runs.
17const DEFAULT_SHELL_SNAPSHOT_TIMEOUT_MS = 6_000;
15// Long enough for a slow but alive server to finish. On timeout the socket asks
16// the same server for the same full snapshot, so a short deadline only throws
17// the first build away. The socket fallback is for setups where /api fails but
18// /ws works, such as a proxy that blocks /api. A dead server is caught by the
19// socket ping, which drops the session and interrupts this load. The cached
20// shell renders while this runs.
21const DEFAULT_SHELL_SNAPSHOT_TIMEOUT_MS = 20_000;
1822
1923/**
2024 * Load the environment shell snapshot (projects + thread shells) over HTTP
packages/client-runtime/src/state/threadSnapshotHttp.ts+7-4
......@@ -13,10 +13,13 @@ import { ManagedRelayDpopSigner } from "../relay/managedRelay.ts";
1313import type { RemoteEnvironmentRequestError } from "../rpc/http.ts";
1414import { executeAuthenticatedEnvironmentHttpRequest } from "./environmentHttpAuth.ts";
1515
16// Bounded so a pathologically slow endpoint cannot block the (cheaper) socket
17// fallback for long. The cached thread renders while this runs, so the wait only
18// delays the transition to live data on the first open, not the initial paint.
19const DEFAULT_THREAD_SNAPSHOT_TIMEOUT_MS = 6_000;
16// Long enough for a slow but alive server to finish. On a cold open a timeout
17// makes the socket ask the same server for the same snapshot again, and older
18// turn pages have no fallback, so a short deadline only drops work. The socket
19// fallback is for setups where /api fails but /ws works, such as a proxy that
20// blocks /api. A dead server drops the socket session, which interrupts a
21// cold-open load. Older turn pages wait for this deadline.
22const DEFAULT_THREAD_SNAPSHOT_TIMEOUT_MS = 20_000;
2023
2124/**
2225 * Load a thread's detail snapshot over HTTP instead of embedding it in the