Tang-mm95/dsh-single-instance-guard
DSH_HOME single-instance lock plugin for DeepSeek Harness: aborts startup loudly when another dsh server uses the same data directory (prevents session-log corruption)
已收录
0
Dev
Bundle 已验证
预览
功能介绍
检测到其他存活的 dsh 实例占用同一 DSH_HOME 数据目录时中止启动,防止并发写会话日志导致的历史损坏。
适合
- 适合桌面封装程序或运维人员可能误启多个服务、并共用同一 DSH_HOME 的 DSH 安装。
- 适合希望把 JSONL 会话存储的并发写损坏转化为明确启动失败的部署。
- 适合需要零依赖目录锁并自动处理失效锁的单机环境。
不适合
- 各服务使用不同 DSH_HOME 根目录时价值有限,因为它们不会争用受保护目录。
- 若通过不同数据根目录刻意指向同一个会话文件,则不适用;这一非支持场景不在锁的保护范围内。
- 不适合确实需要多个存活进程并发写入同一 DSH_HOME 的工作流。
README
dsh-single-instance-guard
A zero-dependency DeepSeek Harness plugin that takes an exclusive lock on the DSH_HOME data directory at startup and aborts loudly when another live dsh server already uses it.
Why
The JSONL session persistence backend documents “One live writer per session” and has no cross-process defense. Two dsh servers sharing one DSH_HOME (a desktop wrapper spawning its own server, or two dsh web processes) append batches with stale sequence cursors, corrupting session logs:
history unavailable for session "…": Error: corrupt session log: seq gap in committed region …
See this report for the full diagnosis, a read-only scanner, and a manual repair procedure.
This plugin turns the silent corruption into a loud startup failure.
Install
After publishing to npm:
dsh plugin --profile <profile> add dsh-single-instance-guard
Manual (any dsh install): add the row to the profile’s cordis.patch.yml before session-related bundles:
- insert:
- id: single-instance-guard
name: 'dsh-single-instance-guard'
The guard is a profile bundle: its manifest declares the same patch, so the CLI installs it as a patch layer.
How it works
- Creates
<DSH_HOME>/.dsh-server.lockatomically (O_EXCL), holding{ pid, startedAt, hostname }. - On conflict, probes the holder’s pid liveness: a live holder aborts startup with a clear bilingual error; a stale lock (dead pid or unparsable file) is removed and acquisition retried once.
- On process exit the lock is removed — only if still owned by this process.
DSH_HOME is resolved exactly like dsh itself: $DSH_HOME or ~/.dsh. Servers with different data roots never conflict.
Known limits
- The unlink+retry path has a tiny race when two processes discover the same stale lock simultaneously; the atomic
O_EXCLwrite still admits exactly one winner, and the loser fails correctly on the retry. - The lock protects against concurrent servers sharing one
DSH_HOME. It does not protect against two dsh instances deliberately pointed at the same session file via different roots (unsupported anyway).
Development
npm test # node --test
License
MIT
常见问题常见问题
在启用了 DSH 的终端中执行已验证命令 dsh plugin --profile default add github:Tang-mm95/dsh-single-instance-guard。命令会解析公开 package 元数据,并保持插件与本页展示的目录身份一致。
兼容性以页面上展示的 bundle 与 profile 状态为准。如果某个 profile 尚未检测到,请先保持禁用,并在生产启用前阅读仓库文档。
GitHub 链接和 activity 元数据是 release 与维护状态的来源。新版本发布后重新查看本页,确认目录已经观察到最新版本。