v0.7.0

Socket Daemon

最後更新

core/daemon 讓所有開啟同一資料目錄的 process 共用一個 unix socket;本頁說明 daemon.New 如何決定該 process 成為 server 或 client。

滿足的需求

# 需求 做法
1 每個 ToriiDB 位置一個共用 socket 第一個 process 開啟唯一的 Store,其他 process 透過 socket 與它溝通
2 不同位置使用不同 socket Socket 名稱是解析後絕對目錄的 hash
3 同位置重複 New 共用 socket New 先撥號;socket 存活即為 client 模式
4 呼叫端不必判斷角色 Get/Set/Del/... 在兩種模式行為一致

傳輸是 unix socket,搭配自訂的長度前綴 JSON frame,不使用 HTTP。

模式判定

daemon.New(dir, apiKey...) 依序執行:

  1. 拒絕空的 dir。
  2. resolveDir:CheckDir(dir, true) → filepath.Abs → filepath.EvalSymlinks。
  3. resolveSocket:/tmp/toriidb-<uid>-<hex(sha256(realDir)[:8])>.sock。
  4. probeSocket:net.DialTimeout("unix", path, 500ms)。
探測結果 模式 New 的動作
撥號成功 ModeClient 建立連線池 client,不開啟 store
ECONNREFUSED 或 ENOENT ModeServer 開啟 store.New(realDir, apiKey...)
其他撥號錯誤 錯誤 回傳 probe socket <path>: ...
設計規則 原因
Socket 目錄固定為 /tmp os.TempDir() 讀 $TMPDIR,socket 會變成取決於環境而非位置
路徑必須經過 EvalSymlinks macOS 的 /tmp 是 /private/tmp 的 symlink;relx、./relx、/tmp/relx/、/private/tmp/relx 與 symlink 必須收斂
存活只以撥號判定,不用 os.Stat kill -9 會留下 socket 檔;殘留檔案不能阻止新 server 啟動
檔名含 uid /tmp 由多個使用者共用
New 吃 dir 而非 *store.Store 探測必須在開啟 store 之前;client 不可對同一目錄再開一個 store

相關頁面

EN