mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-21 01:18:08 +00:00
fix: 网络检测增强 + Tracker changeset 清理
网络检测 (monitor.go): - TCP 拨测 (8.8.8.8:53 / 1.1.1.1:53 / 208.67.222.222:53) - 延迟阈值检测 (>5s 标记降级) - DNS 多目标检测 (google/baidu/cloudflare) - NetworkCheckResult 新增 TCPReachable + LatencyDegraded Tracker: - 新增 WithKeepChangesets / WithMaxChangesetAge 选项 - Init 时自动清理过期 changeset (默认保留100份/30天) - 先按年龄裁剪,再按数量裁剪
This commit is contained in:
@ -7,24 +7,39 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Tracker struct {
|
||||
mu sync.Mutex
|
||||
dataDir string
|
||||
workDir string
|
||||
lowerDir string
|
||||
upperDir string
|
||||
mergeDir string
|
||||
mounted bool
|
||||
active bool
|
||||
before *FSState
|
||||
changeSets []*ChangeSet
|
||||
mu sync.Mutex
|
||||
dataDir string
|
||||
workDir string
|
||||
lowerDir string
|
||||
upperDir string
|
||||
mergeDir string
|
||||
mounted bool
|
||||
active bool
|
||||
before *FSState
|
||||
changeSets []*ChangeSet
|
||||
keepChangesets int // 保留最近 N 份 changeset,0 = 不限
|
||||
maxChangesetAge time.Duration // changeset 最大保留时长,0 = 不限
|
||||
}
|
||||
|
||||
func NewTracker(dataDir, workDir string) *Tracker {
|
||||
return &Tracker{
|
||||
type TrackerOption func(*Tracker)
|
||||
|
||||
func WithKeepChangesets(n int) TrackerOption {
|
||||
return func(t *Tracker) { t.keepChangesets = n }
|
||||
}
|
||||
|
||||
func WithMaxChangesetAge(d time.Duration) TrackerOption {
|
||||
return func(t *Tracker) { t.maxChangesetAge = d }
|
||||
}
|
||||
|
||||
func NewTracker(dataDir, workDir string, opts ...TrackerOption) *Tracker {
|
||||
t := &Tracker{
|
||||
dataDir: dataDir,
|
||||
workDir: workDir,
|
||||
lowerDir: filepath.Join(workDir, "lower"),
|
||||
@ -32,6 +47,10 @@ func NewTracker(dataDir, workDir string) *Tracker {
|
||||
mergeDir: filepath.Join(workDir, "merged"),
|
||||
changeSets: make([]*ChangeSet, 0),
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(t)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *Tracker) Init() error {
|
||||
@ -40,6 +59,7 @@ func (t *Tracker) Init() error {
|
||||
return fmt.Errorf("create overlay dir %s: %w", d, err)
|
||||
}
|
||||
}
|
||||
t.cleanupChangeSets()
|
||||
log.Printf("[tracker] initialized (work=%s)", t.workDir)
|
||||
return nil
|
||||
}
|
||||
@ -172,6 +192,65 @@ func (t *Tracker) saveChangeSet(cs *ChangeSet) {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tracker) cleanupChangeSets() {
|
||||
dir := filepath.Join(t.dataDir, "changesets")
|
||||
entries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
type csFile struct {
|
||||
name string
|
||||
info os.FileInfo
|
||||
}
|
||||
var files []csFile
|
||||
for _, e := range entries {
|
||||
if e.IsDir() || !strings.HasSuffix(e.Name(), ".json") {
|
||||
continue
|
||||
}
|
||||
info, err := e.Info()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
files = append(files, csFile{name: e.Name(), info: info})
|
||||
}
|
||||
|
||||
// 按修改时间排序
|
||||
sort.Slice(files, func(i, j int) bool {
|
||||
return files[i].info.ModTime().Before(files[j].info.ModTime())
|
||||
})
|
||||
|
||||
now := time.Now()
|
||||
remaining := make([]csFile, 0, len(files))
|
||||
|
||||
for _, f := range files {
|
||||
keep := true
|
||||
|
||||
if t.maxChangesetAge > 0 && now.Sub(f.info.ModTime()) > t.maxChangesetAge {
|
||||
keep = false
|
||||
}
|
||||
|
||||
if keep {
|
||||
remaining = append(remaining, f)
|
||||
}
|
||||
}
|
||||
|
||||
// 再按数量裁剪
|
||||
if t.keepChangesets > 0 && len(remaining) > t.keepChangesets {
|
||||
excess := len(remaining) - t.keepChangesets
|
||||
for i := 0; i < excess; i++ {
|
||||
path := filepath.Join(dir, remaining[i].name)
|
||||
os.Remove(path)
|
||||
}
|
||||
remaining = remaining[excess:]
|
||||
}
|
||||
|
||||
if len(files) != len(remaining) {
|
||||
log.Printf("[tracker] cleanup: removed %d changesets, kept %d",
|
||||
len(files)-len(remaining), len(remaining))
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tracker) Rollback() error {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
@ -213,11 +292,13 @@ func (t *Tracker) Stats() map[string]interface{} {
|
||||
totalChanges += len(cs.Files)
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"mounted": t.mounted,
|
||||
"active": t.active,
|
||||
"change_sets": len(t.changeSets),
|
||||
"total_changes": totalChanges,
|
||||
"merge_dir": t.mergeDir,
|
||||
"upper_dir": t.upperDir,
|
||||
"mounted": t.mounted,
|
||||
"active": t.active,
|
||||
"change_sets": len(t.changeSets),
|
||||
"total_changes": totalChanges,
|
||||
"merge_dir": t.mergeDir,
|
||||
"upper_dir": t.upperDir,
|
||||
"keep_changesets": t.keepChangesets,
|
||||
"max_changeset_age": t.maxChangesetAge.String(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user