feat(server): retire scan scheduler for watcher + safety-net walk
Wire the fsnotify watcher and a fixed 12h safety-net delta walk in main; remove the configurable scan scheduler (scheduler.go, scan_schedule table via migration 0033, GET/PATCH /api/admin/scan/schedule, and the server/api plumbing). Manual scan + scan status are unchanged.
This commit is contained in:
+48
-4
@@ -5,12 +5,15 @@ import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/config"
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/coverart"
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/db"
|
||||
@@ -53,6 +56,35 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
// safetyNetScanInterval backstops the fsnotify watcher with a low-frequency
|
||||
// full delta walk, catching anything the watcher missed (inotify watch-limit
|
||||
// exhaustion, dropped events). Fixed — there is no operator configuration.
|
||||
const safetyNetScanInterval = 12 * time.Hour
|
||||
|
||||
// runSafetyNetScans ticks a delta RunScan at safetyNetScanInterval until ctx
|
||||
// is cancelled, deferring to TryStartScan's in-flight guard so it never
|
||||
// collides with a manual, startup, or watcher-driven scan.
|
||||
func runSafetyNetScans(ctx context.Context, pool *pgxpool.Pool, scanner *library.Scanner,
|
||||
enricher *coverart.Enricher, logger *slog.Logger, scanCfg library.RunScanConfig,
|
||||
) {
|
||||
ticker := time.NewTicker(safetyNetScanInterval)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
started, existing, err := library.TryStartScan(ctx, pool, scanner, enricher, logger, scanCfg)
|
||||
if err != nil {
|
||||
logger.Error("safety-net scan: try start failed", "err", err)
|
||||
} else if !started && existing != nil {
|
||||
logger.Info("safety-net scan skipped — prior still in flight",
|
||||
"in_flight_id", existing.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func run() error {
|
||||
configPath := flag.String("config", os.Getenv("MINSTREL_CONFIG"), "path to YAML config file")
|
||||
flag.Parse()
|
||||
@@ -237,12 +269,24 @@ func run() error {
|
||||
ArtistEnrichCap: -1,
|
||||
DataDir: cfg.Storage.DataDir,
|
||||
}
|
||||
scheduler := library.NewScheduler(pool, logger.With("component", "scheduler"),
|
||||
scanner, coverEnricher, scanCfg)
|
||||
scheduler.Start(ctx)
|
||||
// Filesystem watcher: near-instant pickup of new/changed files via
|
||||
// fsnotify, scanning just the affected paths + enriching their albums
|
||||
// inline. Replaces the removed configurable scan scheduler.
|
||||
watcher := library.NewWatcher(scanner, coverEnricher,
|
||||
logger.With("component", "watcher"), cfg.Library.ScanPaths)
|
||||
go func() {
|
||||
if werr := watcher.Run(ctx); werr != nil {
|
||||
logger.Warn("library watcher exited", "err", werr)
|
||||
}
|
||||
}()
|
||||
// Safety-net delta walk backstops the watcher (inotify limits / dropped
|
||||
// events) at a fixed low frequency. No operator config.
|
||||
go runSafetyNetScans(ctx, pool, scanner, coverEnricher,
|
||||
logger.With("component", "scan_safetynet"), scanCfg)
|
||||
|
||||
srv := server.New(logger, pool, scanner, subsonic.Config{
|
||||
AllowPlaintextPassword: cfg.Subsonic.AllowPlaintextPassword,
|
||||
}, cfg.Events, cfg.Recommendation, cfg.Storage.DataDir, cfg.Branding, coverEnricher, coverSettings, scanner, scanCfg, scheduler)
|
||||
}, cfg.Events, cfg.Recommendation, cfg.Storage.DataDir, cfg.Branding, coverEnricher, coverSettings, scanner, scanCfg)
|
||||
srv.Bus = bus
|
||||
srv.PlaylistScheduler = playlistScheduler
|
||||
srv.StreamSecret = cfg.StreamSecret
|
||||
|
||||
Reference in New Issue
Block a user