diff --git a/cmd/root.go b/cmd/root.go index 02a2792a7..d970c9a31 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -53,8 +53,16 @@ func runNavidrome() { db.EnsureLatestVersion() var g run.Group + g.Add(startServer()) - g.Add(startScanner()) + g.Add(startSignaler()) + + interval := conf.Server.ScanInterval + if interval != 0 { + g.Add(startScanner(interval)) + } else { + log.Warn("Periodic scan is DISABLED", "interval", interval) + } if err := g.Run(); err != nil { log.Error("Fatal error in Navidrome. Aborting", err) @@ -76,20 +84,45 @@ func startServer() (func() error, func(err error)) { } } -func startScanner() (func() error, func(err error)) { - interval := conf.Server.ScanInterval +var sigChan = make(chan os.Signal, 1) + +func startSignaler() (func() error, func(err error)) { + scanner := GetScanner() + ctx, cancel := context.WithCancel(context.Background()) + + return func() error { + for { + select { + case sig := <-sigChan: + log.Info(ctx, "Received signal, triggering a new scan", "signal", sig) + start := time.Now() + err := scanner.RescanAll(ctx, false) + if err != nil { + log.Error(ctx, "Error scanning", err) + } + log.Info(ctx, "Triggered scan complete", "elapsed", time.Since(start).Round(100*time.Millisecond)) + case <-ctx.Done(): + break + } + } + }, func(err error) { + cancel() + if err != nil { + log.Error("Shutting down Signaler due to error", err) + } else { + log.Info("Shutting down Signaler") + } + } +} + +func startScanner(interval time.Duration) (func() error, func(err error)) { log.Info("Starting scanner", "interval", interval.String()) scanner := GetScanner() ctx, cancel := context.WithCancel(context.Background()) return func() error { - if interval != 0 { - time.Sleep(2 * time.Second) // Wait 2 seconds before the first scan - scanner.Run(ctx, interval) - } else { - log.Warn("Periodic scan is DISABLED", "interval", interval) - <-ctx.Done() - } + time.Sleep(2 * time.Second) // Wait 2 seconds before the first scan + scanner.Run(ctx, interval) return nil }, func(err error) { diff --git a/scanner/signaler_unix.go b/cmd/signaler_unix.go similarity index 91% rename from scanner/signaler_unix.go rename to cmd/signaler_unix.go index cdf54acd6..919dc5bf2 100644 --- a/scanner/signaler_unix.go +++ b/cmd/signaler_unix.go @@ -1,7 +1,7 @@ // +build !windows // +build !plan9 -package scanner +package cmd import ( "os" diff --git a/scanner/scanner.go b/scanner/scanner.go index 2a3517e91..4cd569d77 100644 --- a/scanner/scanner.go +++ b/scanner/scanner.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "os" "strconv" "sync" "time" @@ -40,10 +39,7 @@ type FolderScanner interface { Scan(ctx context.Context, lastModifiedSince time.Time, progress chan uint32) error } -var ( - isScanning utils.AtomicBool - sigChan = make(chan os.Signal, 1) -) +var isScanning utils.AtomicBool type scanner struct { folders map[string]FolderScanner @@ -87,9 +83,6 @@ func (s *scanner) Run(ctx context.Context, interval time.Duration) { select { case <-ticker.C: continue - case sig := <-sigChan: - log.Info(ctx, "Received signal, triggering a new scan", "signal", sig) - continue case <-ctx.Done(): return }