dshbase

插件目录 / Developer / dsh-large-proj-perf

dsh-large-proj-perf

未验证 orangeofcarl0-sys

✓ 持续维护 基于 1 个官方 DSH 包

查看 GitHub ↗ ← 返回插件目录

1Stars
0Forks
0未关闭 issue
语言
2026-08-21最近推送
跨平台平台

功能简介

DSH large-session performance plugin: zero-copy fork + projection warmup + chunked materialize

我们的评价
未验证 — 尚未实测

DSH large-session performance plugin: zero-copy fork + projection warmup + chunked materialize 尚未验证——请自行安装测试。

「未验证」表示我们的自动化 CI 尚未安装过该插件。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。

你是插件作者? 想拿到「已验证」标签——提交你自己的验证证据(截图、日志或短视频),我们审核通过后即改为「已验证」。

提交验证证据 ↗

README

dsh-large-proj-perf

Version
dsh
dsh-std
License: MIT

DSH(DeepSeek Harness)大会话性能插件:零拷贝 fork、投影分片预热、分片 materialize,
一次装齐,消除 fork/历史加载对超大会话的事件循环阻塞。

⚠️ 版本兼容性警告:本插件通过 monkey-patch dsh 内部方法实现(SessionStore.fork
PersistenceCoordinator.initForJsonlSessionPersistence.encodeMaterialization
SessionPreparations 等),与 dsh 版本高度耦合,当前针对 0.1.0-rc.6 / rc.7 / rc.8
/ 0.1.1-rc.1 开发并验证(rc.7 逐一核对无结构变化;rc.8 仅一处变更且是上游原生
实现了插件的 fastInitFor 优化
——initFor 的 seed 从 structuredClone 深拷贝改为
直接引用 session.events,插件该补丁在 rc.8 起预期退役0.1.1-rc.1 发布说明
无插件相关改动,结构断言与全套测试全过;0.1.1-rc.2 仅图像上传/预处理改动,
五个补丁点子包与 rc.1 逐字节相同)。
dsh 升级后这些内部方法签名可能变化——所有补丁都带源码特征校验,不匹配时自动跳过
优化并回退官方行为
(不会导致崩溃),但优化会静默失效。

运行时版本探针:插件启动时自动探测 dsh 实际版本——已知版本(rc.6/rc.7/rc.8/0.1.1-rc.1/rc.2)打
dsh version: x.y.z (verified),列表外版本打告警并提示跑 tests/verify_compat.mjs
版本也经 stats.get 暴露(value.dshVersion)。升级 dsh 后请确认启动日志无告警
signature mismatch,必要时重新适配本插件。

⚠️ 能力边界(重要):本插件只能缓解超大对话的性能/内存问题(分片、零拷贝、
LRU 裁剪、预热等),无法彻底解决。根本原因在 dsh 的架构——live 会话事件树全量
驻留内存(每个超大会话 ~700MB)、历史加载全量解码 + 逐事件深拷贝。这些是上游架构
问题,插件 monkey-patch 触及不到。真正的根治依赖 dsh 上游支持事件分页加载/按需驻留,
或主动控制会话规模(见下文「避免超长对话」)。

问题

dsh 0.1.0-rc.6 在大会话(数十万事件)上存在三类同步阻塞,导致 fork 卡顿、
历史加载报 signal timed out (internal)、严重时 OOM:

问题 环节 实测
A. fork 深拷贝 Session 构造器逐事件 snapshotJsonValue(纯 JS 深拷贝)+ persistence initForstructuredClone(seed) 18.2MB/20k 事件合计 ~480ms 同步阻塞(rc.8 已原生消除其中 initFor 那次,构造器深拷贝仍在)
B. projection 冷折叠 SessionProjectionRegistry.cellFor() 冷时同步 buildCell 全量折叠 74 万事件冷折叠阻塞 20+ 分钟(100% 单核)
C. fork 全量序列化 fork 子会话首次落盘 encodeMaterializationeventLines = map(JSON.stringify).join("\n") 一次性序列化整个 seed 60 万事件 = 501MB 单字符串;74 万事件直接 RangeError: Invalid string length

为什么「单个会话没事、fork 后出事」:普通会话持久化走增量 appendLines
(每次序列化几十个事件),而 fork 子会话是全新 id,走 materialize 全量序列化
整个 seed——这是唯一会一次性序列化整条日志的路径。

rc.7 / rc.8 上游修了什么(为什么根因仍在)

rc.7:「修复大历史消息分页栈溢出」(commit 5201b848,PR #1371)。
session.history 分页时用 Math.min(event.seq, ...sourceEventSeqs) 展开溯源数组——
一条定稿的 assistant 消息可以通过 sourceEventSeqs 引用数十万个流式分片,
展开超出 JS 引擎函数参数上限(~65535),历史分页请求直接 HTTP 500。修复改为循环
逐项扫描取最小 seq(复杂度仍线性),分页语义不变。上游问题笔记明确声明「本决策
不限制历史记录页面的字节大小,也不限制浏览器回放该页面的开销」——这是 api-proxy
层对已全量解码事件列表的切片逻辑,历史加载全量解码 + 逐事件深拷贝、live 事件树
全量驻留等根因一个都没碰。

rc.8:「改善大历史会话执行分叉操作上的性能耗时」——落实在
PersistenceCoordinator.initFor:seed 从 session.events.map((e) => structuredClone(e))
改为直接引用 session.events上游原生实现了本插件的 fastInitFor 优化,连插件
补丁的 slice() 都比它多一次拷贝)。另「改善 SQLite 后端读写与分叉性能并降低存储
体积,数据结构不兼容」在 dsh-session-query-sqlite(插件不涉及 SQLite 后端,无影响)。
注意:这只消除了 A 类的一半——fork 流程的两个深拷贝里,initFor 那次被上游
原生消除(fastInitFor 补丁退役),但 fork 构造器逐事件的 snapshotJsonValue 深拷贝
仍在
(rc.8 源码核实),它正是 zeroCopyFork 补丁走 fromRestore 通道绕过的核心,
在 rc.8 上仍然必要。B/C 类(投影冷折叠、fork 全量序列化)与历史加载的根因同样仍在,
插件继续兜底。

两版修复都是「可用性 / 单一热点」层面,未触碰架构根因:历史加载仍是 zstd 全量解码

  • 逐事件深拷贝,live 会话事件树仍全量驻留(~700MB/会话)。根治仍依赖上游做事件
    流式解码与按需驻留(另见「能力边界」与「避免超长对话」)。

方案

  1. 零拷贝 forkzeroCopyFork,A):fork 的 seed 事件本就是 deepFreeze
    不可变纯 JSON 树。补丁改走 Session.prepare(..., { seedSource: 'persistence' })
    fromRestore 通道——原地冻结复用引用,跳过整树深拷贝(346ms → 19ms)。
    子会话 header(parentSession/seedLength/cwd)与官方 fork 逐字段一致。
    rc.8 起仍必要:上游只原生消除了 initFor 那次拷贝,fork 构造器的
    snapshotJsonValue 深拷贝依旧存在(rc.8 源码核实)。
  2. fast init-forfastInitFor,A):PersistenceCoordinator.initFor 里那次
    structuredClone(seed) 替换为冻结引用复用(135ms → ~0ms)。带 rc.6 源码特征
    校验(structuredClone(e) 标记),内部结构不匹配时自动跳过并告警。rc.8 起上游
    已原生实现(const seed = session.events),补丁预期退役
    ——特征缺失但检测到
    上游零拷贝形态时打 info 说明,不再误报漂移。
  3. 投影分片预热warmupEnabled,B):会话进入(created/resume)且事件数超过
    阈值时,抢在首次同步冷折叠前,分片重放 cells——每 chunkSize 个事件
    setImmediate 让出事件循环,折叠完成后直写 registration.cells(WeakMap),
    此后 snapshot()/drive() 全部命中热 cell。可用时从投影缓存行取基线跳过已折叠
    前缀。实测 74 万事件:冷折叠 20 分钟 → 预热 200ms。
  4. fork 缓存回填(B,随预热自动执行):fork 子会话(header.parentSession 存在)
    预热完成后立即 cache.write(child) 建立投影缓存行——否则它被放弃时永远没有
    缓存行,下次打开历史 coldSnapshotreadFrom(0) 全量读。
  5. 分片 materializechunkedMaterialize,C):encodeMaterialization
    materializeChunkEvents 个事件一个 zstd frame(多帧是 dsh 解码端
    scanZstdFrames 的原生格式,字节兼容),消除单巨字符串与 RangeError。
  6. 冷会话补行backfillOnBoot,B 辅助,默认关):磁盘缺缓存行的大会话流式
    补写。默认关的原因:readRaw 的 zstd 全量解码是同步的、插件层不可分片,
    大文件仍会冻结事件循环数秒~数十秒。
  7. 冷会话 LRU 裁剪preparedCacheTrim/preparedCacheSize,D):persistence
    的冷会话 LRU 默认缓存 5 个完整事件树(每个大会话 ~700MB,5×700MB 叠加是 OOM
    主因之一)。插件运行时把容量降到 preparedCacheSize(默认 1)并淘汰最旧的
    ready 条目,主动释放冷会话事件树——省 ~2.8GB。无需手动改 cordis.patch.yml
    config.set 运行时改这两个键即时生效;dispose 恢复原 capacity(已淘汰条目
    不复活)。
  8. heap 上限检测heapWarnBytes,D):--max-old-space-size 是 V8 启动期
    参数、进程内改不了。插件检测 heap 上限低于阈值(默认 6GB)时告警,并引导用
    scripts/start-dsh.ps1(内置 --max-old-space-size=8192)重启。

安全性

  • 共享引用等价于深拷贝:事件在进入源会话时已通过完整 JSON 边界与 surface 验证并
    深冻结,任何代码都无法修改。
  • 所有补丁带 rc.6 源码特征校验,内部结构不符自动跳过并告警,绝不盲补。
  • 三层回退:(a) 调用时能力探测缺失 → 官方实现;(b) 补丁内运行时异常 → try/catch
    回退官方实现;(c) 配置开关 → 永远官方路径。
  • dispose 完整还原所有补丁(冷会话 LRU 裁剪恢复 capacity 原值,已淘汰的缓存
    条目不复活)。

安装

# 从 GitHub 安装(推荐)
dsh plugin --profile web add github:orangeofcarl0-sys/dsh-large-proj-perf
# 或
dsh plugin --profile web add https://github.com/orangeofcarl0-sys/dsh-large-proj-perf

# 本地开发
dsh plugin --profile web add file:<本仓库路径>

注意:每次修改仓库代码后,需把 lib/cordis.patch.ymlpackage.json
同步到 <DSH_HOME>/profiles/web/node_modules/dsh-large-proj-perf/file: 安装
不会自动跟随源文件更新),或重新执行 dsh plugin add

重启 dsh web 生效。日志出现 [dsh-perf] installed (...) 即成功。

环境要求:Node ≥ 22.15.0node:zlib 的 zstd 接口所需,低版本加载插件
会直接失败)。package.json 已声明 engines

大会话内存(推荐启动方式)

多个超大会话(数十万事件)的 live 事件树每个 ~700MB,默认 V8 heap 上限 ~4GB
会让 dsh 在内存叠加时 OOM。插件已自动做冷会话 LRU 裁剪(省 ~2.8GB),但 heap
上限是 V8 启动期参数、进程内改不了,推荐用仓库自带脚本启动:

powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\start-dsh.ps1

它等价于 node --max-old-space-size=8192 .../dsh/lib/bin.js web(停止旧进程 →
重启 → 打开浏览器)。若不使用该脚本,插件启动时会打 V8 heap limit ... < ...
告警提醒你加参数。

避免超长对话(主动规避)

本插件做的是「被动优化」——把 fork/历史加载/落盘的大会话阻塞降下来,但无法削减
正在使用的 live 会话事件树(每个 ~700MB,dsh 架构决定全量驻留)。要从根上避免
超长对话的内存/卡顿,推荐配套使用:

  • dsh-fresh-start
    输入 /fresh 一键「总结当前对话 → 开启新对话 → 归档老对话」。在一个会话工作
    一段时间后用它归档,释放 live 事件树内存,而不是让会话无限增长到 70 万+ 事件。
dsh plugin --profile web add github:orangeofcarl0-sys/dsh-fresh-start

两者配合:dsh-large-proj-perf 兜底性能,dsh-fresh-start 主动控制会话规模。

API

POST http://127.0.0.1:3080/dsh-large-proj-perf/api/<method>

  • stats.get — dsh 版本探针(dshVersion)、fork 次数/零拷贝占比/回退、
    预热计数、补行计数、最近记录
  • stats.reset — 清零
  • config.get / config.set — 运行时开关,config.set 同时写 settings 持久化;
    数值项带下限钳制(如 materializeChunkEvents ≥ 1000chunkSize ≥ 1),
    非法值(类型不符/NaN/低于下限取下限)被拒绝或收敛,不会进入危险区间
curl -X POST http://127.0.0.1:3080/dsh-large-proj-perf/api/stats.get
curl -X POST http://127.0.0.1:3080/dsh-large-proj-perf/api/config.set \
  -d '{"zeroCopyFork": false}'

验证

测试依赖真实的 dsh 内部包(@deepseek-ai/dsh-session 等),它们不在本仓库依赖里,
而是全局 dsh 安装的嵌套依赖,Node 解析不到。先链接再跑:

powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\link-deps.ps1
npm test   # 或单独跑:node tests/smoke_fork.mjs
  • tests/smoke_fork.mjs(17 断言):官方 fork 基线 / 零拷贝 fork 功能等价 /
    header 平价(含 origin 不继承)/ seed 前缀逐字节等价 /
    dispose 还原 / 版本漂移回退 —— ALL PASS
  • tests/test_fast_initfor.mjs(10 断言):initFor 补丁安装 / 源码特征漂移跳过 /
    无 persistence 服务存活 / rc.8 上游原生零拷贝形态 → 补丁预期退役(不误报)—— ALL PASS
  • tests/smoke_warmup.mjs(11 断言):分片预热与同步折叠一致 / checkpoint 基线 /
    并发 drive 让位 / dispose 中止 —— ALL PASS
  • tests/test_backfill.mjs(8 断言):fork 回填 / 磁盘冷会话补行 —— ALL PASS
  • tests/test_chunked_materialize.mjs(5 断言):分片多帧解码等价 / 阈值不变 —— ALL PASS
  • tests/test_cache_trim.mjs(18 断言):LRU 裁剪 / dispose 恢复 capacity / 运行时
    开关 / config.set 数值钳制 / 版本探针(stats.get 暴露 dshVersion)—— ALL PASS
  • tests/verify_compat.mjs(16 断言):对真实安装的 dsh 源码做特征断言——
    fork/initFor/encodeMaterialization/toHeaderLine 字段集/SessionPreparations/
    投影注册表与缓存接口/packChunkRuns 导出;版本不在已知列表时打 WARN
  • tests/test_manifest.mjs(21 断言):dsh-std Community v0.15 清单结构断言 /
    entry 文件存在 / overrides 补丁点声明 / std-host facet 模块形态 —— ALL PASS

局限

  • 版本高度耦合(重要):补丁绑定 dsh 内部结构(_forkSeed
    initFor/encodeMaterialization 源码特征、SessionPreparations.capacity 等)。
    已在 0.1.0-rc.6 / rc.7 / rc.8 / 0.1.1-rc.1 上验证;dsh 升级后,特征校验会自动跳过优化并
    回退官方行为(不崩溃、不误补),但优化会静默失效——升级后务必跑
    node tests/verify_compat.mjs(或确认启动日志无 signature mismatch),并按需
    重新适配。本插件不适合在 dsh 版本频繁变动时依赖其优化。
  • enqueue 的逐事件 structuredClone(fork 第三次拷贝)在插件层无法安全消除——
    它在 write-behind 闭包内部,且承担"persistence 独立于生产者"的所有权语义。根治需
    上游改为按需快照。
  • 冷会话 coldSnapshot 的全量 readFrom(0)(zstd 解码 + 逐事件
    snapshotStoredEvents 深拷贝)无法在插件层安全分片——readRaw 的同步解码是硬伤。
    根治需上游把 readFromCore/loadStored 改成分片让出事件循环。
  • 超大会话(70 万+ 事件)加载本身有内存 OOM 风险,与插件无关;建议配合
    dsh-fresh-start 主动归档。

dsh-std 兼容(Community v0.15 清单已实现)

DSH 插件互操作标准已发布 rc:@dsh-std/core / manifest / composition / sdk /
lifecycle(0.1.0-rc1,2026-08-18),核心是 Community v0.15 的 dsh-plugin.json
插件清单
(对象模型 + JSON Schema + 校验器,parseManifest/validateManifest)。
本插件已提供标准兼容面,双轨加载

  • 当前 dsh(0.1.x):继续走 cordis.patch.yml(bundle patch)加载 lib/index.js
    行为不变。
  • 未来标准宿主:按 dsh-plugin.json 加载——facets.host.entry 指向
    lib/std-host.js(facet 激活模块:activate/deactivate/snapshot,形态与
    @dsh-std/sdkdefineFacet 产物等价,但刻意不依赖 @dsh-std 运行时包)。
    宿主若经协议提供 cordis 上下文(未来标准的 cordis.dsh/v1alpha1 ContextProvider
    类钩子),激活时桥接 lib/index.jsapply;否则空激活(补丁不装,符合三层回退)。

清单要点:id(反向域名)、manifestVersion: "0.15"$schema 为 draft URN(不 fetch)、
compat.hosts 声明已验证的 dsh 版本范围(rc.6 ~ 0.1.1-rc.2)、overrides 如实声明
五个补丁点
(fork/initFor/encodeMaterialization/SessionPreparations.capacity/
投影 cells——kind 均为 patch),权限/命令/订阅为空数组。

测试:tests/test_manifest.mjs(21 断言)对清单做结构断言并校验 entry 文件存在;
环境装有 @dsh-std/manifest 时自动升级为官方 validateManifest 真校验。

未来迁移(标准 API 落地后替换补丁,按上游痛点优先级):

  1. 事件流式读取/按需驻留接口——历史加载全量解码根因的官方通道;backfill/预热
    可改基于它,替代 readRaw 全量解码。
  2. fork seed 快照接口——zeroCopyFork 的官方通道,替代 fromRestore 私有通道与
    能力探测。
  3. 投影预热/缓存接口——替代直写 registration.cells(WeakMap)的 hack。
  4. persistence 生命周期钩子——替代 initFor/encodeMaterialization 补丁。

迁移策略建议为「标准 API 优先、现有补丁兜底」的双轨:标准 API 可用时消费契约接口
(特征校验、版本列表、verify_compat 探针随之退役),缺失时回退现有补丁——插件的三层
回退架构本身就是这个接缝。本插件的 engines >=22.15.0 与 dsh-std 的 ^22.19 || >=24
有重叠;一旦消费 dsh-std,需同步提高 engines 声明。

安装

🧩 让 Agent 自动装(推荐)

装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:

dsh plugin add dshbase-catalog

然后对 agent 说「帮我装 dsh-large-proj-perf」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包

该插件是 GitHub 源码(未发 npm)——直接从仓库装:

Web profile:

dsh plugin --profile web add github:orangeofcarl0-sys/dsh-large-proj-perf

Headless(CLI)profile:

dsh plugin --profile headless add github:orangeofcarl0-sys/dsh-large-proj-perf

实测报告

尚未 L3 验证——若已跑过,见下方失败备注。

状态:pending · 最近测试 2026-08-26
备注:验证: runtime-fail 浏览全部待验证失败 →
安全:尚未扫描——我们的每日静态扫描将很快覆盖它。

分享徽章

Developer 里更多

浏览全部 7795 个插件 →