Fix race condition in scanner

This commit is contained in:
Deluan 2022-11-29 11:08:47 -05:00
parent 10cd3152ba
commit d8c5944ef1

View file

@ -12,13 +12,11 @@ import (
"github.com/navidrome/navidrome/log" "github.com/navidrome/navidrome/log"
"github.com/navidrome/navidrome/model" "github.com/navidrome/navidrome/model"
"github.com/navidrome/navidrome/server/events" "github.com/navidrome/navidrome/server/events"
"github.com/navidrome/navidrome/utils"
) )
type Scanner interface { type Scanner interface {
RescanAll(ctx context.Context, fullRescan bool) error RescanAll(ctx context.Context, fullRescan bool) error
Status(mediaFolder string) (*StatusInfo, error) Status(mediaFolder string) (*StatusInfo, error)
Scanning() bool
} }
type StatusInfo struct { type StatusInfo struct {
@ -39,7 +37,7 @@ type FolderScanner interface {
Scan(ctx context.Context, lastModifiedSince time.Time, progress chan uint32) (int64, error) Scan(ctx context.Context, lastModifiedSince time.Time, progress chan uint32) (int64, error)
} }
var isScanning utils.AtomicBool var isScanning sync.Mutex
type scanner struct { type scanner struct {
folders map[string]FolderScanner folders map[string]FolderScanner
@ -139,12 +137,11 @@ func (s *scanner) startProgressTracker(mediaFolder string) (chan uint32, context
} }
func (s *scanner) RescanAll(ctx context.Context, fullRescan bool) error { func (s *scanner) RescanAll(ctx context.Context, fullRescan bool) error {
if s.Scanning() { if !isScanning.TryLock() {
log.Debug("Scanner already running, ignoring request for rescan.") log.Debug("Scanner already running, ignoring request for rescan.")
return ErrAlreadyScanning return ErrAlreadyScanning
} }
isScanning.Set(true) defer isScanning.Unlock()
defer isScanning.Set(false)
defer s.cacheWarmer.Flush(ctx) defer s.cacheWarmer.Flush(ctx)
var hasError bool var hasError bool
@ -199,10 +196,6 @@ func (s *scanner) setStatusEnd(folder string, lastUpdate time.Time) {
} }
} }
func (s *scanner) Scanning() bool {
return isScanning.Get()
}
func (s *scanner) Status(mediaFolder string) (*StatusInfo, error) { func (s *scanner) Status(mediaFolder string) (*StatusInfo, error) {
status := s.getStatus(mediaFolder) status := s.getStatus(mediaFolder)
if status == nil { if status == nil {