Repository navigation
ci(wsl): real WSL2 lane for WSL via orcad (C10) - #27921
Conversation
|
Lane results: green on two consecutive runs (run 38229195911, attempts 1 and 2; head 4cf275d)
Each distro in phase 1 (plain / systemd, attempt 2): first connect took 12.1 / 13.2 s. Killing orcad was detected in 322 / 309 ms, and the relaunch with a census (liveSessions 1, the terminal survived) took 6.3 / 6.9 s. Iterations before green:
Open issue (C3): |
9ac0ba7 to
2b419a3
Compare
4cf275d to
b597049
Compare
b597049 to
d9df88c
Compare
2b419a3 to
caf2132
Compare
ff9a098 to
b80ef82
Compare
7d5d2c4 to
4e4aa55
Compare
… (WSL-via-orcad C10)
b80ef82 to
7c21149
Compare
📝 Walkthrough
Priority: ⬇️ Low Merge Risk: 🔵 Low · up to
|
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
19b2b436-444d-40dc-baf1-f2dc721aec23
📒 Files selected for processing (2)
.github/workflows/wsl-orcad-e2e.ymlsrc/main/wsl/wsl-orcad-real-distro-lane.test.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.
| function guest(distro: string, command: string): Promise<string> { | ||
| return execCommand(transportFor(distro), command, { timeoutMs: 60_000 }) | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
#!/bin/bash
rg -nP -C5 'createWslCommandLoopPool|dispose' --type=ts -g '*wsl-command-loop*'Repository: stablyai/orca
Length of output: 7445
🏁 Script executed:
set -eu
printf '%s\n' '--- guest and transport call sites ---'
rg -n -F -- 'function transportFor' src/main/wsl/wsl-orcad-real-distro-lane.test.ts
rg -n -F -- 'function guest' src/main/wsl/wsl-orcad-real-distro-lane.test.ts
rg -n -F -- 'createWslOrcadHostTransport' src/main/wsl src/main
printf '%s\n' '--- lane excerpt ---'
nl -ba src/main/wsl/wsl-orcad-real-distro-lane.test.ts | sed -n '70,125p'
printf '%s\n' '--- transport declarations and implementation references ---'
rg -n -F -- 'createWslOrcadHostTransport' src
rg -n -F -- 'execWithClosedStdin' src/main
rg -n -F -- 'function execCommand' src/main
printf '%s\n' '--- candidate source files ---'
rg --files src/main | rg 'wsl|ssh-relay-exec-command'Repository: stablyai/orca
Length of output: 26577
🏁 Script executed:
set -eu
printf '%s\n' '--- host transport ---'
nl -ba src/main/wsl/wsl-orcad-host-transport.ts | sed -n '1,180p'
printf '%s\n' '--- exec command ---'
nl -ba src/main/ssh/ssh-relay-exec-command.ts | sed -n '1,135p'
printf '%s\n' '--- command-loop pool ---'
nl -ba src/main/wsl/wsl-command-loop-pool.ts | sed -n '1,145p'
printf '%s\n' '--- transport type/disposal usage ---'
rg -n -F -- 'WslOrcadHostTransport' src/main/wsl src/main/ssh
rg -n -F -- '.dispose()' src/main/wsl/wsl-orcad-* src/main/wsl/*transport* src/main/sshRepository: stablyai/orca
Length of output: 24592
🏁 Script executed:
set -eu
printf '%s\n' '--- guest call sites and helper ---'
rg -n -F -- 'guest(' src/main/wsl/wsl-orcad-real-distro-lane.test.ts
rg -n -F -- 'expectNoGuestBridges' src/main/wsl/wsl-orcad-real-distro-lane.test.ts
printf '%s\n' '--- lane control flow ---'
nl -ba src/main/wsl/wsl-orcad-real-distro-lane.test.ts | sed -n '240,480p'
printf '%s\n' '--- loop idle/end behavior ---'
nl -ba src/main/wsl/wsl-command-loop.ts | sed -n '1,190p'Repository: stablyai/orca
Length of output: 18896
Dispose the per-command WSL transport.
guest() creates a new command-loop pool for each command. Without disposal, the pool can keep its wsl.exe loop alive for up to the 5-second idle timeout. This can delay teardown and leave a WSL client running after the command completes.
Suggested fix
--- "a/src/main/wsl/wsl-orcad-real-distro-lane.test.ts"
+++ "b/src/main/wsl/wsl-orcad-real-distro-lane.test.ts"
@@ -103,9 +103,14 @@
}
/** As the distro's default user, through the same transport orcad's deploy uses. */
-function guest(distro: string, command: string): Promise<string> {
- return execCommand(transportFor(distro), command, { timeoutMs: 60_000 })
+async function guest(distro: string, command: string): Promise<string> {
+ const transport = transportFor(distro)
+ try {
+ return await execCommand(transport, command, { timeoutMs: 60_000 })
+ } finally {
+ transport.dispose()
+ }
}
async function wslExe(args: string[], timeoutMs = 60_000) {
const result = await runProcess({📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function guest(distro: string, command: string): Promise<string> { | |
| return execCommand(transportFor(distro), command, { timeoutMs: 60_000 }) | |
| } | |
| async function guest(distro: string, command: string): Promise<string> { | |
| const transport = transportFor(distro) | |
| try { | |
| return await execCommand(transport, command, { timeoutMs: 60_000 }) | |
| } finally { | |
| transport.dispose() | |
| } | |
| } |
Stacked on #27916.
ELI5
Orca is learning to run its server inside a WSL Linux distro on Windows. This adds a CI check that does that for real on a GitHub Windows machine: it creates two fresh Ubuntu distros, starts Orca's server in each, talks to it, breaks it on purpose, and checks Orca notices and recovers.
What Changed
.github/workflows/wsl-orcad-e2e.yml(not a required check). It runs on PRs that touchsrc/main/wsl/**,src/main/ssh/orcad-*,src/main/ssh/remote-install-transport.tsor the workflow itself.linux-x64-glibcorcad template. That is the one artifact the distro needs, and its node-pty slot builds only on Linux. No Electron build.windows-2025job first installs a checksum-pinned, cached WSL 3.0.1 MSI. The image ships WSL 2.7.14, and on that version stopping a systemd distro drops the VM-wideWSLInteropentry (binfmt config cleared on all distro when distro with systemd is terminated microsoft/WSL#13885). The lane caught this on its first run. It installs the MSI rather than runningwsl --update, becausewsl --updatecalls the GitHub API and got a 403 from the runner.src/main/wsl/wsl-orcad-real-distro-lane.test.ts, skipped unlessORCA_RUN_WSL_ORCAD_LANE=1on Windows. It runs in two processes:status.get, runsrepo.addon a freshgit init, and creates a terminal whose output token it reads back. Then it kills orcad withkill -9and expectsreconnecting(orcad-exited)followed byreadywith a census and a new pid. Next it runswsl --terminateand expectsdistro-stoppedwithterminals: exited, and nothing boots the distro again. Finally it reconnects. After the systemd distro is terminated, it checks thatWSLInteropstill exists.live. It reconnects, then tears down. Teardown must leave no guest bridge processes, all holders released, and nowsl.exebridge or holder processes. It checksWSLInteroponce more after the systemd distro stops.WSLInteropentry is re-registered as root, and the lane still fails.Why
This is the C10 step of WSL via orcad. The spike (#27783) showed hosted
windows-2025runs WSL2 reliably, so this uses a hosted runner rather than a self-hosted one. It is a gated vitest, likeorcad-windows-host-lane.test.ts, rather than a Playwright spec, because none of this needs the app UI. That keeps the lane to one template build plus a Node install. Running the test as two processes is what proves the holder outlives the process that spawned it.Linked Issue
N/A (internal plan step C10)
Visual Proof
N/A: CI only, no UI change.
Testing
The new lane is the test. It passed on two consecutive runs (run 38229195911, attempts 1 and 2). Timings are in a comment below. Typecheck passes locally (
pnpm tc:node).AI Disclosure
Review
Agent skill upstream boundary
Notes
Ensure no issues in: Security, Cross-platoform support (Linux, Windows, Mac), Remote SSH, Mobile, general backwards compatibility, performance
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)