dsh-single-instance-guard:DSH 單實例鎖插件

前言

DeepSeek Harness (DSH) 的 JSONL 會話持久化後端遵循“每個會話一個活躍寫入器”的策略,本身不具備跨進程的防禦機制。如果兩個 dsh 服務器共享同一個 DSH_HOME(例如桌面包裝器自行啓動服務器,或同時運行兩個 dsh web 進程),它們會使用過期的序列游標追加批次,導致會話日誌損壞,報錯信息通常爲 corrupt session log: seq gap in committed region。

dsh-single-instance-guard 插件旨在將這種靜默的損壞轉化爲啓動時的明確失敗,通過獨佔鎖定防止併發啓動。

插件概述

該插件是 DeepSeek Harness 的一個零依賴插件,由 Tang-mm95 維護,採用 MIT 許可證。它的核心作用是在啓動時對 DSH_HOME 數據目錄進行原子獨佔鎖定。如果檢測到另一個 dsh 服務器正在使用該目錄,插件將中止啓動。

核心功能

  1. 原子獨佔鎖定:在 <DSH_HOME> 目錄下創建 .dsh-server.lock 文件,文件內容包含 { pid, startedAt, hostname }。使用 O_EXCL 標誌確保創建操作的原子性。
  2. 併發檢測與中止:檢測到衝突時,先探測鎖定持有者的進程存活狀態。若持有者存活,則中止當前啓動並顯示雙語錯誤;若持有者已不存在,則移除鎖並重試一次。
  3. 自動清理:進程退出時,僅當鎖文件仍屬於該進程時,自動移除鎖文件。
  4. 零依賴:不依賴任何第三方庫。

安裝與配置

可以通過 CLI 安裝,也可以手動配置。

CLI 安裝

dsh plugin --profile <profile> add dsh-single-instance-guard

手動配置

在 profile 的 cordis.patch.yml 中添加以下行。必須確保該配置位於會話相關 bundles 之前:

- insert:
    - id: single-instance-guard
      name: 'dsh-single-instance-guard'

工作原理

插件首先解析 DSH_HOME(優先級爲 $DSH_HOME 或 ~/.dsh)。隨後嘗試創建 .dsh-server.lock 文件。

  1. 成功:文件創建成功,插件持有鎖。
  2. 衝突:文件已存在。插件讀取文件內容並檢查對應 PID 的進程是否存活。存活則報錯退出;若 PID 不存在或文件格式無法解析,視爲過期鎖,刪除後重試一次。
  3. 退出:進程結束時,檢查文件中的 PID 是否仍爲當前進程,是則刪除鎖文件。

適用場景與注意事項

該插件適用於需要確保同一 DSH_HOME 目錄下只有一個 dsh 服務器運行的環境。

需要注意以下限制:
* 極小的競態條件:當兩個進程同時發現並嘗試刪除同一個過期鎖時,存在極小的競爭窗口。但原子 O_EXCL 寫入機制確保了只有一個進程能最終獲取鎖,另一個進程會在重試時正確失敗。
* 路徑保護:僅保護同一 DSH_HOME 路徑下的併發服務器。對於指向同一個 session 文件但路徑不同的兩個 dsh 實例,插件無法保護。
* 環境要求:需要 Node.js >= 18。

總結

通過引入此插件,可以在 DSH 環境中避免因併發啓動導致的會話日誌損壞問題。相關源碼與文檔可在其 GitHub 倉庫查看。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜