QoderWake 高 CPU / 卡死问题处理报告
处理日期:2026-10-21
======================================================================
一、问题现象
环境:
- macOS 27.0.1 (26A434),Apple Silicon,10 核,24GB 内存
- QoderWake 1.1.13(官方最新版本)
- daemon buildCommitId:44db7cc66adc2dc00e9068757b262beb99dbef96
- 进程:~/.qoderwake/qoderwake __daemon --host 127.0.0.1 --port 19820
表现:
- daemon 持续占用 97%–99% 单核 CPU
- 启动 31 分钟,累计 CPU 时间 30 分钟以上
- 内存占用 3.1–3.35GB RSS
- 主线程 100% 卡在 Bun/JavaScriptCore JIT 中,事件循环周期性完全阻塞
- 健康接口 /api/v1/system/health 持续超时
- 菜单栏每 10 秒探活全部失败
- 日志出现 61–121 秒的 clock gap
- WorkPoller poll success 单次耗时 100,472ms
- 对 openapi.qoder.sh 的请求大量超时
- Qoder 主程序未受影响,问题只在 QoderWake daemon
======================================================================
二、根因
-
云端群会话输出目录过大
路径:
~/.qoderwake/data/cloud-conversations/conv_01m4t3gvfxvpj61br01a59qbfr/shared
该目录共 57,258 个文件 / 2.3GB
其中 shared/poc0/build 单独占 56,635 个文件 -
artifact finalization 全量扫描该目录
为 3 个已停止会话生成 38,464–38,473 个 artifact:- 242bd7b8-4e19-445f-af91-4ac99315c5c3(agent 1da45af493a9):清单 44MB
- cac13fa9-2d40-4dcb-a4ef-7a4c11710136(agent 857846bd9468):清单 44MB
- 8b6b3c68-8358-4392-bf4e-72095fc39667(agent d979b097af42):清单 31MB
-
finalization 因快照缺失不断重试
错误:
GroupSessionArtifactOutboxService
Group artifact outbox pending: run=crun_…
error=GROUP_ARTIFACT_SNAPSHOT_MISSING每次重试都会重新扫描目录,并反序列化、比对 31–44MB 的清单。
session-artifact-finalizations 中约每 90 秒生成一对 pending/receipt,
并通过 nextAttemptAt 不断续期。 -
数据库被撑大
数据库大小:572MB- storage_records:392MB
- session_runtime_events:91MB
- 3 个会话的文件变更记录:131,752 条
-
最终结果
主线程被 artifact 处理占满,HTTP 服务、心跳、轮询全部超时,
表现为 QoderWake 卡死并持续占用 CPU。
关键日志:
[WakeRecovery] clock gap detected, running recovery: {“gapMs”:121086,…}
[WorkPoller] poll success: {“durationMs”:100472.63,“workCount”:1,…}
[GroupSessionArtifactOutboxService] Group artifact outbox pending:
run=crun_… error=GROUP_ARTIFACT_SNAPSHOT_MISSING
[PresentFilesTool] artifact manifest updated:
… artifactsAdded=38464, presented=38464
[SessionFileChangeStore] derived file changes replaced:
… deleted=53904, written=53904
======================================================================
三、处理过程
处理时间:2026-10-21 21:27–21:35
所有操作可回滚,原始文件未删除。
-
停止 QoderWake
退出菜单栏应用,并终止 daemon(PID 1043)。
CPU 立即恢复。 -
备份
SQLite 数据库(572MB)备份到:
/Users/Lonnie/Documents/QoderWake-quarantine/2026-10-21/db-backup/qoderwake.sqlite配置文件同时备份:
- settings.json
- config.json
-
隔离大目录
将以下目录移动到隔离区:
~/.qoderwake/data/cloud-conversations/conv_01m4t3gvfxvpj61br01a59qbfr/shared/poc0/build
→
/Users/Lonnie/Documents/QoderWake-quarantine/2026-10-21/conv_01m4t3gvfxvpj61br01a59qbfr/shared/poc0/build移动大小:2.3GB
移动文件数:56,635
artifact 扫描根目录文件数从 57,258 降到 623。 -
清理派生状态
在 daemon 停止状态下,通过 SQLite 事务删除:- 3 个超大 artifact 清单(共约 119MB)
- 3 个 artifact baseline
- 131,752 条 session-file-changes 记录
- 103 条相关 session-artifact-finalizations 记录
并执行 wal_checkpoint(TRUNCATE)。
-
重启
执行 qoderwake start
重新打开 QoderWake 菜单栏应用。
======================================================================
四、验证结果
- CPU:从持续 99% 降到平均 15%–25%(单核百分比)
仅有短暂尖峰,不再持续满载。 - 内存:从 3.1GB 降到 2.1GB,稳定不增长。
- 健康接口:返回 200,耗时 11ms(此前持续超时)。
- 重启后:0 次 clock gap,0 次健康超时。
- daemon 正常监听 127.0.0.1:19820。
- QoderWake 应用正常运行,33 个会话,0 个正在运行。
- 最大 artifact 清单从 44MB 降到 2MB。
======================================================================
五、当前仍存在的现象
- 旧云端群会话的 artifact 补传仍会偶发:
GROUP_ARTIFACT_SNAPSHOT_MISSING - finalization 仍会在 21:31、21:34 对 8b6b3c68 发起重试,
但每次只扫描 623 个文件,不再阻塞主线程。 - 数据库中仍有约 74 条 pending finalization,
其中 47 条 sessionId 为空;单次处理已很轻。 - QoderWake Console 在 Edge 中打开,会轮询旧 run 的
execution-artifacts,从而触发 finalization 尝试。
关闭或归档旧群会话后,可彻底消除剩余重试。 - 2.3GB 构建产物保存在隔离目录中,需要时可原样移回。
======================================================================
六、给官方的修复建议
-
对 artifact 扫描增加硬限制
单次最多 N 个文件、N 字节、N 层目录深度。
默认忽略 build、dist、node_modules、.venv、target、.git 等生成目录。 -
finalization 重试不要每次全量重扫
持久化扫描游标或文件指纹,目录无变化时直接跳过。
GROUP_ARTIFACT_SNAPSHOT_MISSING 应终止或降级,
而不是无限续期重试。 -
将 artifact 扫描、清单序列化、diff 移出主线程
限制单个 manifest 大小,避免一次性加载 30–40MB JSON。 -
启动时检测异常大的 artifactOutputRoots
超过阈值应跳过并告警。
提供 CLI 清理卡住的 finalization/outbox。 -
增加 artifact ignore 配置项
并增加单会话 artifact 数量上限。
======================================================================
七、回滚方法
-
停止 daemon
cd ~/.qoderwake && ./qoderwake stop -
将隔离的构建产物移回
mv /Users/Lonnie/Documents/QoderWake-quarantine/2026-10-21/conv_01m4t3gvfxvpj61br01a59qbfr/shared/poc0/build
~/.qoderwake/data/cloud-conversations/conv_01m4t3gvfxvpj61br01a59qbfr/shared/poc0/build -
如需恢复数据库
cp /Users/Lonnie/Documents/QoderWake-quarantine/2026-10-21/db-backup/qoderwake.sqlite
~/.qoderwake/data/store/qoderwake.sqlite注意:恢复旧数据库会重新引入高 CPU 问题。
======================================================================
八、相关文件
日志:
~/.qoderwake/logs/qoderwake.log
~/.qoderwake/logs/qoderwake.1.log
数据库备份:
/Users/Lonnie/Documents/QoderWake-quarantine/2026-10-21/db-backup/qoderwake.sqlite
隔离的构建产物:
/Users/Lonnie/Documents/QoderWake-quarantine/2026-10-21/conv_01m4t3gvfxvpj61br01a59qbfr/shared/poc0/build
======================================================================
