Files
arcrun-collector/sync_status.go
T
Leo bf1f0d9991 feat(t104): 多帳號同時看守——切換概念消滅
leo 架構依據:「它只是一個門,幾個帳號通過它同步並沒有影響」+
「我不是 Google Drive……不提供暫存空間,daemon 工作輕巧,多帳號只是頁簽問題」
(D-daemon-not-Drive)。
Accounts[] 每帳號獨立連線+資料夾;舊 config 冪等遷移 accounts[0];
逐帳號同步一敗不擋全;status.json 分帳;托盤每帳號一分組;
「連上知識庫」→「+新增帳號…」(append 非替換);t86 切換清空退役;
t101 刪除作用於正確帳號。+873/-149、collector 5+tray 5 新測試,
兩模組 go test 全綠(總管親跑)。
(實作=子 CC;驗證+commit=總管)
2026-07-28 16:45:14 +08:00

73 lines
3.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// sync_status.go — 每輪同步後的彙總狀態(t91 狀態可見性)。
// 寫成 JSON 供托盤讀取,讓使用者第一眼看到萃取是否正常。
package main
import (
"encoding/json"
"os"
"path/filepath"
)
// AccountSyncStatus 彙總單一帳號的每輪同步結果(t104 多帳號看守)。
// key in SyncStatus.AccountDetails = instanceHostOf(cypher_url)。
type AccountSyncStatus struct {
LastSync string `json:"last_sync,omitempty"`
CloudVersion string `json:"cloud_version,omitempty"` // t103 per-account
CloudCheckOK bool `json:"cloud_check_ok"`
ExtractedOK int `json:"extracted_ok"`
ExtractFailed int `json:"extract_failed"`
}
// SyncStatus 彙總每輪同步的萃取結果,持久化至 ~/.arcrun-rag/status.json。
// 托盤依此決定顯示「已萃 N 檔」、「⚠ 萃取失敗 M 檔」還是「⚠ 萃取引擎未就緒」。
type SyncStatus struct {
LastSync string `json:"last_sync,omitempty"` // RFC3339,最近一輪完成時間
ExtractedOK int `json:"extracted_ok"` // 本輪萃取成功件數(跨帳號累計)
ExtractFailed int `json:"extract_failed"` // 本輪萃取失敗件數(跨帳號)
Failures []ExtractFail `json:"failures,omitempty"` // 失敗清單(路徑+白話原因)
ExtractorOK bool `json:"extractor_ok"` // 萃取器本身是否就緒(預檢,機器層級)
ExtractorError string `json:"extractor_error,omitempty"` // 未就緒的白話原因
// 頂層 cloud 欄位保留向後相容(單帳號時同時填頂層+AccountDetails
CloudVersion string `json:"cloud_version,omitempty"` // bundle_version(單帳號時填)
CloudCheckOK bool `json:"cloud_check_ok"` // /health 可達才為 true
// t104per-account 狀態(key = instanceHostOf(cypher_url)
AccountDetails map[string]AccountSyncStatus `json:"account_details,omitempty"`
}
// ExtractFail 記一筆萃取失敗(路徑+白話原因)。
type ExtractFail struct {
Path string `json:"path"`
Error string `json:"error"`
}
// StatusFilePath 回傳狀態檔路徑:與 manifest 同目錄的 status.json。
func StatusFilePath(manifestPath string) string {
return filepath.Join(filepath.Dir(manifestPath), "status.json")
}
// SaveSyncStatus 寫入(覆蓋)狀態檔。失敗只印 stderr,不擋看守本體。
func SaveSyncStatus(path string, s SyncStatus) error {
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
return err
}
data, _ := json.MarshalIndent(s, "", " ")
return os.WriteFile(path, data, 0o644)
}
// LoadSyncStatus 讀取狀態檔;不存在或解析失敗回零值+error(托盤自行降級)。
func LoadSyncStatus(path string) (SyncStatus, error) {
var s SyncStatus
data, err := os.ReadFile(path)
if err != nil {
return s, err
}
err = json.Unmarshal(data, &s)
return s, err
}
// SyncNowSignalPath 回傳立刻同步訊號檔路徑:與 manifest 同目錄的 sync-now。
// tray 寫入此檔 → collector 偵測到後立刻跑一輪同步並刪除它。
func SyncNowSignalPath(manifestPath string) string {
return filepath.Join(filepath.Dir(manifestPath), "sync-now")
}