@mcd0luo/celes-dsh-session-guard
v0.1.0
Published
Session mutex guard for dsh (Celestea series): a lock-file + heartbeat warning layer that detects two processes (dsh web / desk) cross-writing the same session log (INC-001)
Maintainers
Readme
@mcd0luo/celes-dsh-session-guard
dsh 会话互斥守护(Celestea 系列成员)。
背景(INC-001):dsh web 与 desk/gui 双进程无锁共享同一份
~/.dsh/sessions/<项目>/<sessionId>/session.jsonl.zstd,各自维护内存 seq 与
append 偏移,写入交叉会把会话日志写坏(seq gap in committed region)。
本插件是尽力而为的告警层:它不锁官方存储(官方存储本身无锁,也禁不起 插件加锁),只负责让第二个打开同一会话的表面进程看到醒目的红色警示条, 提醒「二选一,别同时开」。
功能
- 会话打开期间,浏览器半每
pollMs轮询一次状态路由(兼作锁心跳); - 检测到另一进程正持有同一会话的写锁 → 输入框上方显示红色警示条:
⚠ 会话互斥:另一个进程(PID xxx)正在写此会话,继续操作可能损坏会话日志; - 可选:持有锁时显示极淡的「已独占」指示(默认关闭)。
实现方式
- 不 patch 官方 client bundle:使用官方
conversation.input.dock槽位挂载 (session 作用域,渲染器给组件注入sessionId标准 prop),纯加法扩展。 - 锁机制(host 半,锁文件 + 心跳 + 陈旧判定):
- 锁目录:
<DSH_HOME 或 ~/.dsh>/.session-locks/(不存在自动创建); - 锁文件:
<sessionId 安全化后的文件名>.lock,内容{"pid": <进程 pid>, "time": <时间戳>},每次获取/轮询写回(touch = 心跳); - 判定:文件不存在 → 写入 →
acquired;持有者是自己 → touch →acquired; 持有者存活(process.kill(pid, 0))且未超过staleMs→conflict(不覆盖); 否则视为陈旧锁 → 覆盖接管 →acquired(带stale: true标注); 锁文件内容损坏 →free(不写不动,避免干扰对方正在进行的写入)。
- 锁目录:
- Host 半注册
celestea-session-guard设置命名空间 +/api/session-guard/status,可在 设置 → Celestea → session-guard 调整。
安装
Celestea 系列由基座 @mcd0luo/dsh-celestea 的 bundle 统一挂载(基座补丁给每个
成员预留带条件的挂载行,本包装进 profile 后下次启动自动启用)。
⚠️ 基座必须显式安装一次。
# 1. 一次性:安装基座(设置中心 + 系列挂载点)
dsh plugin --profile web add @mcd0luo/dsh-celestea
# 2. 安装本包,重启后自动挂载
dsh plugin --profile web add @mcd0luo/celes-dsh-session-guard
# 3. 重启 desk(或 dsh web + 硬刷新)不装基座、单独使用本包时(不推荐),需要手动在
~/.dsh/profiles/web/cordis.patch.yml 添加:
- insert:
- id: session-guard
name: "@mcd0luo/celes-dsh-session-guard"走了基座 bundle 路线就不要再加这行,否则 loader 会报
duplicate loader entry id。
配置(设置 → Celestea → session-guard)
| 字段 | 默认 | 说明 |
|---|---|---|
| enabled | true | 是否启用守护 |
| staleMs | 30000 | 锁超时判定(毫秒):持有进程存活且未超过该时长才算冲突,否则按陈旧锁接管 |
| pollMs | 5000 | 浏览器半轮询间隔(毫秒),兼作锁心跳 |
| showAcquired | false | 持有锁时是否显示极淡的「已独占」指示 |
局限
- 尽力而为的告警层:不阻止写入,只提示。desk 与 web 对同一会话只能开 一个,冲突警示出现时请停掉另一个进程的该会话。
- 锁基于 pid + 时间戳,进程崩溃后锁会在
staleMs后自动过期(陈旧接管); pid 被系统复用是极小概率误判来源。 - 两个进程轮询间隔不同步,冲突检测最多滞后一个
pollMs。
开发
npm run build # src/ → lib/(host + client 都生成)
npm publish # 发版后 dsh plugin --profile web update @mcd0luo/celes-dsh-session-guard兼容性
基于 @deepseek-ai/dsh 0.1.0-rc.6 的 conversation.input.dock 槽位与
sessionId 标准 prop(渲染器硬编码注入),属于官方内部契约,后续 dsh 升级
可能需要同步。
License
MIT
