diff --git a/apps/web/src/connection/desktopLocalDiscovery.expbkt3.ts b/apps/web/src/connection/desktopLocalDiscovery.expbkt3.ts new file mode 100644 index 000000000000..9e31cf9f9ac4 --- /dev/null +++ b/apps/web/src/connection/desktopLocalDiscovery.expbkt3.ts @@ -0,0 +1,15 @@ +/** + * T3-CUSTOM(expbkt3): how long a desktop-local backend may take to describe itself. + * + * The platform source builds every registration before it hands any of them + * to the registry, so the primary environment is not connected until each + * desktop-local backend has answered. A managed build starts its bundled + * backend after the window opens, and a backend still starting holds every + * request until startup finishes. With the default 10 s request timeout, a + * window opened during that start waited 10 s before it even asked the + * remote primary for a WebSocket ticket. + * + * A ready loopback backend answers in milliseconds. One that misses this + * deadline is skipped for this poll and retried on the next one, 3 s later. + */ +export const DESKTOP_LOCAL_DESCRIPTOR_TIMEOUT_MS = 1_500; diff --git a/apps/web/src/connection/platform.ts b/apps/web/src/connection/platform.ts index 3cb074f54d1c..261d3c46422c 100644 --- a/apps/web/src/connection/platform.ts +++ b/apps/web/src/connection/platform.ts @@ -77,6 +77,8 @@ import { connectionStorageLayer } from "./storage"; import { clientPresentationMetadata } from "./clientMetadata"; // T3-CUSTOM(expbkt3): focus wakeups probe unless the window was away >= 60 s. import { type FocusWakeup, makeFocusWakeupTracker } from "./focusWakeup.expbkt3"; +// T3-CUSTOM(expbkt3): desktop-local discovery must not delay the primary. +import { DESKTOP_LOCAL_DESCRIPTOR_TIMEOUT_MS } from "./desktopLocalDiscovery.expbkt3"; let nextObservedRpcRequestId = 0; @@ -411,9 +413,11 @@ const loadSecondaryConnectionRegistration = Effect.fn( } const httpBaseUrl = entry.httpBaseUrl; const wsBaseUrl = entry.wsBaseUrl; - const descriptor = yield* fetchRemoteEnvironmentDescriptor({ httpBaseUrl }).pipe( - Effect.mapError(mapRemoteEnvironmentError), - ); + const descriptor = yield* fetchRemoteEnvironmentDescriptor({ + httpBaseUrl, + // T3-CUSTOM(expbkt3): a starting local backend must not hold up the primary. + timeoutMs: DESKTOP_LOCAL_DESCRIPTOR_TIMEOUT_MS, + }).pipe(Effect.mapError(mapRemoteEnvironmentError)); const issuedAtEpochMs = yield* Clock.currentTimeMillis; const access = yield* bootstrapRemoteBearerSession({ httpBaseUrl,