Environment
- Qoder: 1.19.2 (VSCodium 1.106.3, commit 89941185e4)
- OS: Windows → WSL2 Ubuntu 20.04
- WSL 配置: memory=6GB, swap=2GB, processors=4
- 连接方式: Remote-WSL
Reproduction Steps
- 通过 Qoder 连接 WSL,打开任意目录(如
/home/qing)→ 一切正常 - 使用
File → Open Folder切换到其他目录(如/home/qing/go/src或/home/qing/go/src/llm-d/llm-d-router) - 窗口触发 Reload Window
- Reload 后开始频繁 reconnect,每隔几秒循环一次,完全无法使用
补充说明:
- 第一次连接永远正常,只有 Open Folder 切换后触发
- 与目标目录文件数量无关(打开
/home/qing文件更多但正常,打开单个项目llm-d-router也会循环) - 如果在 Windows 侧直接用新窗口打开 WSL 中的目标目录(不走 Open Folder),则正常
Expected Behavior
Open Folder 切换工作区后,Reload Window 一次即恢复正常连接。
Actual Behavior
Reload Window 陷入无限循环:连接 → 2~14秒后断开 → 重连 → 再断开 → 循环。
Root Cause Analysis
通过分析 ~/.qoder-server/data/logs/ 下频繁重连的日志,发现是 workspace storage 锁竞争 导致的 reload 循环:
循环机制
Open Folder → Reload Window
→ 旧 Extension Host 被 terminate,锁标记 "6000ms 后释放"
→ 新 Extension Host 立即启动(<2s),尝试获取锁
→ EEXIST: vscode.lock 已存在,elapsed < 6000ms,判定非 stale,放弃
→ 使用备用锁 (xxx-1/vscode.lock)
→ 渲染进程检测到异常,再次发送 terminate
→ 循环
关键日志
1. 锁竞争(exthost/remoteexthost.log):
[error] Error: EEXIST: file already exists, open '/home/qing/.qoder-server/data/User/workspaceStorage/32df426cb7af36a347ed6120fb7ec54c/vscode.lock'
[info] Lock '...vscode.lock': Could not acquire lock, checking if the file is stale.
[info] Lock '...vscode.lock': The lock does not look stale, elapsed: 50728 ms, giving up.
[info] Lock '...32df426cb7af36a347ed6120fb7ec54c-1/vscode.lock': Lock acquired.
2. 渲染进程主动 terminate(exthost/remoteexthost.log):
[info] Extension host terminating: received terminate message from renderer
3. 客户端 graceful disconnect(remoteagent.log):
[info] The client has disconnected gracefully, so the connection will be disposed.
[info] Extension Host Process exited with code: 0, signal: null.
[info] Last EH closed, waiting before shutting down
4. 新 server 启动后收到旧 token(remoteagent.log):
[error] [ManagementConnection] Unknown reconnection token (never seen).
[error] [ExtensionHostConnection] Unknown reconnection token (never seen).
5. 重连频率(日志目录时间戳):
20260729T092222
20260729T092245 (+23s)
20260729T092859
20260729T092934 (+35s)
20260729T093010 (+36s)
20260729T093042 (+32s)
20260729T093119 (+37s)
20260729T093224 (+65s)
20260729T093328 (+64s)
11 分钟内产生了 9 次 server 重启。
核心问题
锁释放有 6000ms 延迟(Marking the lockfile as scheduled to be released in 6000 ms),但渲染进程在 ~2s 后就发起了重连。新 Extension Host 拿不到主锁,渲染进程认为工作区状态异常,再次触发 reload,形成死循环。
在本地文件系统上这个时间窗口可能足够小不会触发,但 WSL 的 9P 文件系统放大了延迟,使竞态条件必现。
Suggested Fix
- 客户端在 reload 前应等待旧 Extension Host 完全退出并释放锁,而不是固定时间后直接重连
- 新 Extension Host 获取锁失败时,应重试等待而非立即使用备用锁,避免渲染进程检测到不一致状态
- 或者:Open Folder 在 WSL Remote 下应复用当前 server 进程,仅切换 workspace,而非完整的 terminate → restart 流程
Workaround
- 不使用 Open Folder 切换目录,改为在 Windows 侧用新窗口直接打开 WSL 目标路径
- 或手动删除
~/.qoder-server/data/User/workspaceStorage/*/vscode.lock后再 Open Folder(可打断循环但不根治)