orangeofcarl0-sys/dsh-projection-warmup
orangeofcarl0-sys★ 0JavaScript最后同步: 2026-08-15
DSH projection warmup plugin: chunked live-session warmup + fork cache backfill to eliminate 'signal timed out' event-loop stalls
README 摘要
dsh-projection-warmup DSH(DeepSeek Harness)projection 分片预热插件。 问题 dsh 0.1.0-rc.6 的 projection 冷折叠是同步的: SessionProjectionRegistry.cellFor() 在 cell 冷时对整个 session.events 逐事件 apply() ,大会话(数十万事件)是分钟级 纯 CPU 计算,期间 Node 事件循环冻结,所有 30s 超时的 unary RPC(历史加载、UI 操作) 批量超时,前端表现为「signal timed out (internal)」。实测 74 万事件会话冷折叠阻塞 20+ 分钟(100% 单核)。 方案 1. live 会话分片预热 (v0.1,默认开):会话进入(created/resume)且事件数超过 阈值时,抢在首次同步冷折叠前,分片重放 cells——每 chunkSize 个事件 setImmediate 让出事件循环,折叠完成后直写 registration.cells (WeakMap), 此后 snapshot() / drive() 全部命中热 cell。可用时从投影缓存行取基线跳过已折叠 前缀。实测 74 万事件会话: 冷折叠 20 分钟 → 预热 200ms 。 2. fork 子会话缓存回填 (v0.2,默认开,零成本):fork 子会话 ( header.parentSession 存在)预热完成后立即 cache.write(child) 建立投影缓存 行——否则它被放弃时永远没有缓存行,下次打开历史 coldSnapshot 走 readFrom(0) 全量读(分钟级阻塞)。 3. 磁盘冷会话后台补行 (v0.2, 默认关 ):扫描缺缓存行的大日志,流式 parse + fold 后 putSoft 写行。默认关闭的原因: readRaw 内部的 zstd 全量解码 是同步的、插件层不可分片,对大文件仍会冻结事件循环数秒 数十秒;且启动期补行 与 dsh 自身的启动投影折叠叠加会推高内存峰值(有 OOM 风险)。需要时经 config.set 打开。 安装 API POST http://127.0.0.1:3080/dsh-projection-warmup/api/ : - stats.get / stats.reset — 预热/补行计数与明细 - config.get / config.set — 运行时开关 局限与上游建议 - 冷会话 coldSnapshot 的全量 readFrom(0) (含 zstd 解码 + 逐事件 snapshotStoredEvents 深拷贝)无法在插件层安全分片—— readRaw 的同步解码是硬伤。 根治需上游把 readFromCore…
在 GitHub 查看完整 README →