fix(desktop): WSL backend connects with Docker bridges and slow cold starts - #6129
fix(desktop): WSL backend connects with Docker bridges and slow cold starts#6129rehanhaider wants to merge 3 commits into
Conversation
getDistroIp took the first IPv4 from `hostname -I`, which prints every bound address in interface order. A distro running Docker reports its br-*/docker0 bridges first, so the desktop pointed the renderer at an address Windows cannot reach and sat on "Connecting to WSL..." until the readiness budget expired. It also defeated the mirrored-networking check in DesktopBackendConfiguration, which only collapses to loopback when the reported address belongs to a Windows interface; a bridge address never matches. Print the default route's source address ahead of the `hostname -I` output so the existing first-match parser picks it up. `hostname -I` still trails it, so distros without iproute2, or with no default route, keep today's behaviour. The lookup targets 192.0.2.1 (RFC 5737) and is a routing-table query, so no packet is sent. Verified on Windows 11, WSL2 mirrored networking, three Docker bridges: hostname -I -> 172.18.0.1 172.17.0.1 172.19.0.1 192.168.1.5 route source -> 192.168.1.5 Before, readiness targeted the 172.18.0.1 bridge and never resolved. After, isLocalHostIpv4 matches 192.168.1.5 against the host adapter and readiness targets http://127.0.0.1:<port>, which answers 200. Closes pingdotgg#5211.
The desktop probes backend readiness once with a 60s budget. A WSL backend loads the server bundle and its dependencies across /mnt/c, so cold boot regularly exceeds that. When it does the probe gives up, the run is left alive but never ready, and the app sits on "Connecting to WSL..." forever even though the backend finishes booting seconds later and answers 200 on its readiness endpoint. Measured on Windows 11 with WSL2, two consecutive launches: run 1: gave up at 60000ms; backend healthy shortly after run 2: gave up at 60000ms; backend listening and answering 200 at 98s The probe polls every 100ms and resolves the instant the backend answers, so a larger budget costs nothing when boot is fast. Refs pingdotgg#4535, pingdotgg#5522.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Needs human review This PR modifies WSL connection logic, including how the distro IP is determined. While the intent is to fix connection issues, changes to IP detection on the critical connection path warrant human verification to ensure correctness across different WSL configurations. You can customize Macroscope's approvability policy. Learn more. |
What Changed
getDistroIpnow prefers the default route’s source address, withhostname -Ias the fallback.DEFAULT_BACKEND_READINESS_TIMEOUTincreases from 1 to 3 minutes.Scope: two files, 19 lines, two commits. No tests added—the changes are one shell string and one constant.
Why two commits and not one?
Both commits fix the same user-visible hang, so they ship together.
Both causes the exact same symptoms to the user.
Happy to split if you'd rather take them separately.
Why
On Windows, the desktop can remain on “Connecting to WSL…” when Docker is running inside the distro. The backend starts, listens, and answers readiness checks, but the app targets the wrong address and times out too early. Either bug can cause the hang.
Wrong address
getDistroIppreviously selected the first IPv4 address fromhostname -I, which lists all bound addresses in interface order. With Docker running, abr-*ordocker0bridge can appear first, directing the renderer to an address Windows cannot route to.This also breaks mirrored networking.
isLocalHostIpv4inDesktopBackendConfigurationmaps the backend to loopback only when the reported address belongs to a Windows interface. A Docker bridge does not match, so mirrored-mode users lose the intended loopback path.The new command asks the kernel for the default route’s source address using
ip -4 route get 192.0.2.1. This avoids interface-name matching and RFC1918 heuristics without adding another spawn. The route source is printed beforehostname -I, allowing the existing first-match parser and IPv4 validation to remain unchanged.hostname -Iremains the fallback, so distros without iproute2 or a default route behave as they do today.192.0.2.1is reserved by RFC 5737, and this is only a routing-table lookup—no packet is sent.Readiness timed out too early
Readiness currently receives a single 60-second budget. Loading the server bundle and dependencies across
/mnt/cregularly takes longer. When the probe expires, the backend process remains alive but is never marked ready, leaving the splash visible even if startup completes seconds later.The probe polls every 100 ms and resolves immediately when the backend responds, so increasing the budget does not slow fast launches.
Verification
Verified on Windows 11 with WSL2 mirrored networking and three active Docker bridges—the topology reported in #5211:
Before the timeout change, with the address fix already applied:
After both changes:
The address fix is evidenced by the route lookup above: hostname -I returns the bridge first, so the previous first-match selection resolves to 172.18.0.1, which Windows cannot route to. Measurements were taken against a dev build (dev:desktop), which also waits on the Vite server, so the 98s figure is not directly a packaged-build number.
Validation:
vp test run apps/desktop/src/wsl/DesktopWslEnvironment.test.ts apps/desktop/src/backend/DesktopBackendManager.test.tsAll 52 tests passed. Typecheck and lint are clean for both changed files.
Related Work
This area is active:
There could be more robustness in the solution but I have preferred simple, tested, and workable solution instead.
Closes #5211
Refs #4535 and #5522.
Checklist
Note
[!NOTE]
Fix WSL distro IP detection and extend backend readiness timeout
getDistroIpImplin DesktopWslEnvironment.ts to prefer the IPv4 source address of the default route (ip -4 route get 192.0.2.1) before falling back tohostname -I, which is more reliable in multi-interface WSL environments.DEFAULT_BACKEND_READINESS_TIMEOUTin DesktopBackendManager.ts from 1 minute to 3 minutes to accommodate slower WSL startup times.getDistroIpImplmay differ in environments with multiple network interfaces.Macroscope summarized a702228.