灵犀桌面客户端 1.3.31 主进程同步目录遍历导致长时间“未响应”
标题:灵犀桌面客户端 1.3.31 主进程同步目录遍历导致长时间“未响应”(附根因定位与修复建议)
环境:灵犀桌面客户端 v1.3.31(由 1.3.27 升级,app-server 5.15.0),Windows 11,i3-13100 / 16GB
现象:升级 1.3.31 后主窗口反复进入“未响应”状态:所有交互无反应,CPU 单核满载,持续数分钟(实测约 222 秒)后自行恢复,不崩溃。1.3.27 版本同样存在,升级后未修复。复现概率与工作区文件数量正相关。
复现步骤:
项目/工作区挂载包含大量文件的本地目录(如数万文件的代码仓库、测试 fixture 目录);
打开项目或触发文件扫描(项目初始化、文件列表加载);
主窗口很快“未响应”,CPU 单核 100%,持续数十秒至数分钟;
期间 logs/app/app.*.log 日志写入完全停止。
证据:
2026-11-02 17:45:14 应用日志戛然而止约 222 秒后恢复,与主进程事件循环被阻塞的特征完全吻合;
该时段主窗口 Responding=False,进程 CPU 持续累积(忙转而非死锁);
logs/process-metrics/*.log 分钟级快照显示扫描时段 CPU 与内存同步飙升(渲染进程内存 488MB→665MB,系统 sys CPU 93%)。
初步根因(分析 resources/app.asar 中 out/main/index.js):工作区目录遍历函数(日志通道 walk-dir,含文案 "skip unreadable directory" / "walkDir failed")使用 readdirSync/lstatSync/statSync 同步递归遍历整个目录树;文件计数函数同样基于同步 readdirSync。遍历数万级文件目录时单次调用耗时数分钟,期间事件循环完全阻塞,所有 IPC 排队、窗口消息得不到处理。该遍历由项目文件列表加载(recursive: true)等常规操作触发,日常使用即可复现。
修复建议:
改用 fs/promises 异步 API 逐层 await 遍历;
分片间周期性让出事件循环(如每 N 个条目 await setImmediate());
大目录增加遍历上限/分页策略;
对照验证:改为异步 + 让出事件循环后,相同工作区下不再复现“未响应”。
可提供:完整 app 日志、process-metrics 指标数据,可配合复现调试。