v0.6.0

生命週期

追蹤 daemon 從啟動到關閉的過程,以及期間有哪些 goroutine 並行執行。

啟動順序

runServer 以 --daemon 在新 session 中啟動目前執行檔,將 stdout 與 stderr 導向 daemon.log,並每 100 ms 輪詢一次 endpoint 檔案,最多 10 秒。runServerDaemon 接著依下列順序初始化:

  1. 以新 UID、PID 與啟動時間寫入 runtime.uid。失敗(包含已有另一個存活的 daemon)只記錄警告,啟動繼續。
  2. 初始化 service kuradb 的 keychain context。
  3. 建立 OpenAI embedder;缺少憑證時程序結束。
  4. 開啟 global.db、預載符合預期維度的 query embedding,並註冊將新 query embedding 持久化的 hook。
  5. 初始化 gse tokenizer 與 process-wide vector cache。
  6. 從 db.json 載入 database registry;讀取錯誤時程序結束。
  7. 對每個已註冊資料庫:確保目錄與 ~/Kura_{db} 符號連結存在、開啟 data.db、建立 vector bucket,並從已 embedding 且未 dismiss 的 row 重建 bucket。
  8. 為每個已載入資料庫啟動一個 embedding scheduler 與一個 watcher。
  9. 在 127.0.0.1 啟動 HTTP server、寫入 endpoint,並等待 SIGINT 或 SIGTERM。

data.db 開啟前的單一資料庫失敗會略過該資料庫。Vector bucket 建立失敗時,該資料庫仍可做關鍵字查詢,但不會啟動 watcher 與 embedder。

並行模型

工作 Goroutine 協調方式
Watcher 每個已載入資料庫一個,10 秒 ticker 寫入 record.json 的 snapshot 在 goroutine 中執行,以 mutex 保護
Embedding scheduler 每個已載入資料庫一個,5 秒 ticker 每批最多 64 個 pending chunk
搜尋 未指定 target 時,keyword 與 semantic 分支並行執行 search.Search 內的 sync.WaitGroup,所有 transport 共用
Query cache 持久化 每個新 query embedding 一個短命 goroutine 每次寫入 global.db 逾時 5 秒
HTTP server 一個 listener goroutine 與一個 shutdown 監看者 Context 取消

SQLite 透過 go-sqlkit 提供八條 read connection 與獨立 write connection。Vector cache 使用 cache 層級與每個 bucket 各自的 RWMutex;query cache 有自己的 RWMutex。

關閉流程

終止 signal 會取消共用 context,各部分各自反應:

部分 動作
HTTP server 移除 endpoint,再以 5 秒逾時呼叫 Shutdown
Watcher 與 embedder 離開 select loop
主 goroutine 清除 runtime.uid、關閉所有 per-database connector,最後關閉 global.db

主 goroutine 不等待 HTTP shutdown 或各 loop 結束,因此程序可能在進行中的請求完成前就退出。kura stop 會送出 SIGTERM,5 秒後程序仍存活則升級為 SIGKILL。

EN