You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
于是「新建会话」这条链路会随运行时间变慢,直到某一次(尤其 Windows Modern Standby 睡眠唤醒之后)彻底卡住:宿主已经把会话建出来了,UI 没有切过去,用户继续点,就累积出一串空白壳。重启之所以有效,是因为它把上面三样东西一起清零了。
English summary
On DSH Desktop 0.2.1-rc.2 (Windows), "after some uptime, creating a new conversation hangs for minutes; restarting fixes it" is explained by three compounding factors: (1) every session that was ever opened is permanently promoted to a live Agent — there is no session/close in the RPC surface and teardown is bound to the host root context, so nothing is reclaimed while the host lives; (2) each Agent mounts its own skill-filesystem watcher (watchFile at 100 ms + chokidar) and every new session re-scans all skill roots because the collect cache key includes the per-session scope chain (guaranteed miss); (3) cordis dispatches every event over one global listener table linearly, so per-event cost grows with the number of sessions opened in this process. A Modern Standby/wake cycle then turns the accumulated cost into a multi-minute hang. Related existing threads: #10827, #10683, #9392, #9264, #10336.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
TL;DR
Windows 桌面版 0.2.1-rc.2 上,「用一阵子 → 新建对话半天不动 → 重启才恢复」可以在不改任何插件的前提下用三个叠加因素解释:
session/close、拆除只绑在宿主根 ctx —— 宿主进程活着就永不回收;skill-filesystem监视器(watchFile({interval: 100})10 Hz 轮询 + chokidar),并且每次新建会话都会全量重扫技能目录(技能 collect 缓存 key 含每会话新 scope,必然 miss);emit都线性遍历全部监听 → 单次事件成本随「本次运行打开过的会话数」增长;renderer 的会话列表快照也是 O(会话数) 全量重建。于是「新建会话」这条链路会随运行时间变慢,直到某一次(尤其 Windows Modern Standby 睡眠唤醒之后)彻底卡住:宿主已经把会话建出来了,UI 没有切过去,用户继续点,就累积出一串空白壳。重启之所以有效,是因为它把上面三样东西一起清零了。
English summary
On DSH Desktop 0.2.1-rc.2 (Windows), "after some uptime, creating a new conversation hangs for minutes; restarting fixes it" is explained by three compounding factors: (1) every session that was ever opened is permanently promoted to a live Agent — there is no
session/closein the RPC surface and teardown is bound to the host root context, so nothing is reclaimed while the host lives; (2) each Agent mounts its ownskill-filesystemwatcher (watchFileat 100 ms + chokidar) and every new session re-scans all skill roots because the collect cache key includes the per-session scope chain (guaranteed miss); (3) cordis dispatches every event over one global listener table linearly, so per-event cost grows with the number of sessions opened in this process. A Modern Standby/wake cycle then turns the accumulated cost into a multi-minute hang. Related existing threads: #10827, #10683, #9392, #9264, #10336.环境
D:\杂工作区 108 个会话;工作区 3 个 MCP(rea / pico-dev-knowledge / 12306)为 profile 级单例常驻app.asar内 0.2.1-rc.2 的 bundle,不是源码仓库推断现场 A:Modern Standby 唤醒后的创建风暴
createdAt是同一毫秒1793291374606;4 个永久停在 317–321 B 的 header-only卡死期间那 4 个会话解压后的完整内容是 191 B 的 header(
isSeeded:false),一行事件都没有 —— 这与 @PerryLink 在 #9392 里的更正一致:header-only 本身是「新建但从未打开」的正常形态,真正的问题是宿主建好了、UI 没有切过去,用户于是重复点击。也就是说症状不落在「创建失败」,而落在「创建 + 切过去的这条 UI 链路被拖到不可用」。现场 B:健康实例上的对照数字
同一个实例、4 个并发 agent 的情况下,新建会话到
turn/start只要 2.9–3.6 s;同一台机器上:D:\杂58,855 文件 / 5,830 目录 / 2.1 GB 全量递归 + 逐文件 stat:1.16 s(PowerShellGet-ChildItem口径 7.7 s)D:\杂根目录不是 git 仓库(git rev-parse报 not a git repository),所以 workspace-changes 的 git 快照不参与⇒ 磁盘/内存/历史规模都只能给出「秒」级代价,给不出 30 s 以上、且重启即消失的卡顿。只剩「进程内累积」这一解释。
机制(0.2.1-rc.2 asar 行号)
M1(主因候选)打开过的会话永久变常驻 live Agent,没有任何回收路径
dsh-client-ui-workspace/lib/client.js:1499startSession→:1403connectBlank→:1406/1437sessions.create→dsh-api-session-controller/lib/index.js:755create→:765agents.createSession→:264/:508/:517ctx.agents.create→dsh-agent-loop/lib/index.js:1893createAgent→:1865persistence.create(写session.v4.jsonl.zstd)→:1681prepare()→presets.mount挂 ptc preset(约 30 个插件实例)→:1794agents.announcefollow()(:1510)→:1586-1593promote()把这个会话在后台 resume 成常驻 live Agent;dsh-api-session-controller/lib/typert.host.js:1426-1955)没有任何session/close,全包搜不到demote/evict/ idle 回收;teardown 只绑在根 ctx(dsh-agent-loop/lib/index.js:1749)⇒ 宿主存活期内不释放;dsh-agent-loop/lib/index.js:1989read(0, void 0)、:1995seed: [...persisted]),并持有日志写句柄 + flock(dsh-session-persistence/lib/…:621-639,close 在dsh-agent-loop:1726)。⇒ 内存 / 句柄 / watcher / 事件监听,都随「本次运行打开过的会话数」线性增长,重启清零。
M2(放大器)全局监听表 + O(n) dispatch
cordis/lib/index.js:230,258-264:全应用共用一张_hooks,每次emit都对该事件的全部监听做.filter(scope).map(bind);监听只在 dispose 时移除。每个 agent 插件还会注册session/event、fs/observed等,打开会话时再追加 2–3 个{global:true}(:1529,1537,1546)⇒ 单次事件成本 O(存活会话数)。M3(每次新建的固定成本)技能全量重扫且缓存必 miss
dsh-skill/lib/index.js:270,299:技能 collect 的缓存 key 含scopeChain,新会话 = 新 scope ⇒ 必然 miss ⇒ 逐 rootreaddir+ 读 + 解析SKILL.md(dsh-skill-filesystem/lib/index.js:92-107,584-617)。本机 3 个技能根合计约 150 个技能(~/.dsh/skills26、~/.agents/skills49、内置若干)。附:每个 Agent 一套 100 ms 技能 watcher
dsh-skill-filesystem/lib/index.js:26,36-41,341-348使用watchFile轮询、:370-383使用 chokidar;watchMaxProjects = 128对单个 workspace 永不淘汰。N 个打开过的会话 = N 套 10 Hz 轮询 + N 套目录监听。附:renderer 侧 O(会话数)
dsh-client-ui-workspace/lib/client.js:3585-3618buildListSnapshot、:3622applyMutation是 O(会话数) 全量重建;projectionStores只在 remove 时删除(:3521)。为什么完全符合「刚启动不卡 → 越用越卡 → 重启恢复」
这与 #10827(用着用着卡死/新建没反应/重启恢复/归档后好一点)、#10683(宿主已建会话但 UI 无反馈、同毫秒多个会话、activation ladder +0.055 s → +64.4 s)在现象与数字上完全对得上;#9264(open() 对老会话 O(N) 扫全库,p50 1167 ms @ N≈1830)与 #10336(workspace-changes 每会话 scratch 目录在 TEMP 里不 dispose,60 GB)属于同一类「没有回收路径」的问题。
用户侧临时缓解(不改代码)
skill-filesystem加{ watch: false }(Settings → General 的 preset 编辑器,或覆写cordis.patch.yml的 preset 层)——砍掉每会话一套 10 Hz watcher;代价是技能文件改动不再热更新,重启后生效;session-projection-cache的writeEveryEvents/writeIntervalMs,减少每步写盘。建议的修复方向
session/close(客户端可显式关闭)+ 空闲 LRU 上限(例如同时 live 的 Agent 数 / 总内存阈值),而不是把 teardown 绑在宿主根 ctx;skill-filesystem的 watcher 全局共享或按需启停,不要每个 Agent 一套 100 ms 轮询;技能 collect 缓存 key 不要含scopeChain(或给跨会话共享的稳定 key);%APPDATA%\@deepseek-ai\dsh-desktop\logs为空),社区只能靠会话文件的 zstd 时间戳反推现场,建议加可开关的文件日志(至少记录 create/follow/promote 的耗时)。如何验证 M1(约 10 分钟)
DeepSeek Harness.exe中带dsh-desktop-host的那个)的 Working Set / Handles:预期每打开一个上涨一截且不回落;session/added、follow、promote三段耗时(Session 创建被静默吞掉:宿主已建会话但 UI 无任何反馈(ui-workspace 0.2.1-rc.2) #10683 的 activation ladder 就是这条链路)。补充说明:M1–M3 是 0.2.1-rc.2 代码库的静态分析(行号来自 asar 实包),尚无 CPU profile 坐实;时间线、会话文件大小、磁盘/内存排除项、进程与 CPU 数据均为实测。欢迎直接用上面的验证步骤打脸或补充。
All reactions