Files
2026-04-29 23:38:43 +02:00

80 lines
1.4 KiB
Go

package watchdog
import (
"log/slog"
"orbits-server/internal/server/bootstrap"
"orbits-server/internal/server/database"
"time"
"gorm.io/gorm"
)
type State struct {
FS map[string]struct{}
DB map[string]database.File
}
type Result struct {
FSOrphans []string
DBOrphans []database.File
}
func Kickoff(env bootstrap.Environment, db *gorm.DB) {
interval := time.Second * time.Duration(env.WatchdogInterval)
ticker := time.NewTicker(interval)
go func() {
defer ticker.Stop()
run(env, db)
running := false
for range ticker.C {
if running {
slog.Warn("watchdog is still running, skipping tick")
continue
}
running = true
func() {
defer func() { running = false }()
run(env, db)
}()
}
}()
}
// the watchdog has 2 tasks
// 1 revoke expires keys
// 2 remove / sync orphaned files/db records
func run(env bootstrap.Environment, db *gorm.DB) {
slog.Debug("watchdog cycle start")
revokeExpired(db)
fsState, err := scanFS(env)
if err != nil {
slog.Error("scanFS failed", "error", err)
return
}
dbState, err := scanDB(db)
if err != nil {
slog.Error("scanDB failed", "error", err)
return
}
result := reconcile(fsState, dbState)
if len(result.FSOrphans) > 0 {
slog.Info("filesystem orphans detected")
applyFS(env, db, result.FSOrphans)
}
if len(result.DBOrphans) > 0 {
slog.Info("database orphans detected")
applyDB(db, result.DBOrphans)
}
}