Thanks to visit codestin.com
Credit goes to github.com

Skip to content

【Bug】持久化路径随会话工作区漂移,导致历史用量数据"消失/统计为 0",且 UI 显示路径与实际落盘路径不一致 #4

Description

@mumuer1024

环境

  • 插件:@feiyang666/dsh-usage-plugin v1.9.1
  • DSH:Web 版(profile: web),Windows 10
  • 会话工作区:%USERPROFILE%\Documents\dsh

问题现象

  1. 每次启动 DSH 后、在产生新对话之前,插件读取/写入的用量文件是用户主目录下的
    %USERPROFILE%\dsh-usage\usage-records.json,而不是工作区路径。

  2. 一旦产生新对话(会话绑定工作区)后,插件切换为读写
    %USERPROFILE%\Documents\dsh\dsh-usage\usage-records.json

  3. 统计页顶部显示:

    数据持久化:%USERPROFILE%\dsh-usage\usage-records.json(每次调用实时落盘,插件重启后自动恢复,最多保留 100000 条)

    但这条路径只是启动时的临时根目录,会话激活后真实数据落在工作区文件里——UI 显示的持久化路径与实际落盘路径不一致

  4. 重启后历史用量数据"消失",统计页显示 0:历史数据躺在其它工作区/路径的 dsh-usage/usage-records.json 里,重启时插件只读取当前选中根目录的那一份,不跨路径合并,因此总量被拆散。

证据

机器上同时存在多份 usage-records.json(均为本插件产生):

路径 状态
%USERPROFILE%\dsh-usage\usage-records.json(含 .keep 占位文件) 启动时根目录解析为主目录时创建,含本会话 19:37–20:08 的记录,之后不再增长
%USERPROFILE%\Documents\dsh\dsh-usage\usage-records.json 会话激活后持续写入(观察期间 9601→11203 字节持续增长)
%USERPROFILE%\.dsh\dsh-usage\usage-records.json 内容为 [],更早一次根解析的残留

根因分析

存储根目录的解析完全取决于会话工作区/cwd,而非固定路径(lib/index.js):

  • initPersistence() 的候选根依次为:agent.session.header.cwdsandboxPolicy.workspaceRoot → 由 fs.resolve('dsh-usage-probe') 推导的 cwd。
  • 启动时还没有会话工作区workspaceRoot 解析到用户主目录 %USERPROFILE%,于是根被设为该目录,读写 %USERPROFILE%\dsh-usage\usage-records.json
  • 会话激活后ensureSessionRoot() 发现 policy.workspaceRoot 变为工作区路径,调用 tryInitWithRoot(工作区) 把根切换为工作区,开始读写 Documents\dsh\dsh-usage\usage-records.json
  • tryInitWithRoot() 切换根时会把内存中的 records 整体写回路径,但不做跨根的数据合并/迁移;重启后 initPersistence() 只读取它当前选中根(主目录)的那一份文件。

客户端渲染(lib/client.js 约 1145 行):

el("div", { style: st.note }, "数据持久化:" + dataPath + "(每次调用实时落盘,插件重启后自动恢复,最多保留 100000 条)")

其中 dataPath 来自 /usage/api 返回的当前根路径,随根切换而变化,因此显示值不可靠。

预期行为 vs 实际行为

  • 预期:持久化路径固定且唯一;UI 显示的路径与真实落盘路径一致;重启后自动恢复全部历史记录(无论记录之前落在哪个根)。
  • 实际:持久化路径随"是否有会话/会话工作区"漂移;UI 显示的路径与实际落盘路径不一致;历史记录被拆散在多份文件中,重启后仅恢复当前根的那一份 → 表现为"数据消失/统计为 0"。

建议修复方向

  1. 支持固定持久化目录配置:允许用户(或默认)指定一个稳定的目录存放 usage-records.json,不再随工作区漂移(例如固定到 $DSH_HOME/dsh-usage/ 或用户配置目录)。
  2. 启动时合并去重:若确实按工作区分目录存储,则启动时应把"主目录 + 当前工作区 + 配置目录"等所有已知位置的记录读取合并(现有 normalizeRecord + 按 time 去重的逻辑可直接复用),而不是只读当前根。
  3. UI 路径与真实路径保持一致:统计页显示的"数据持久化"路径应始终等于实际写入路径;若根会切换,应同步更新并说明。
  4. (可选)切换根目录时对旧根做一次真正的数据迁移,避免复制/分裂。

复现步骤

  1. 以某个工作区启动 DSH,安装并启用本插件。
  2. 未发送任何对话前,查看统计页:显示"数据持久化:<主目录>\dsh-usage\usage-records.json"。
  3. 发送一条消息产生用量记录,再次查看:此时记录实际写入 <工作区>\dsh-usage\usage-records.json
  4. 重启 DSH 后查看统计:仅恢复主目录文件中最后写入的那部分记录,其余历史(落在工作区/其它路径的)不显示,表现为统计大幅减少或为 0。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions