fix(scanner): resolve data race on conf.Server access in getScanner
Captured DevExternalScanner config value in the controller struct at construction time instead of reading the global conf.Server pointer in getScanner(). The background goroutine spawned by ScanFolders() was reading conf.Server.DevExternalScanner concurrently with test cleanup reassigning the conf.Server pointer, causing a data race detected by the race detector in the E2E test suite.
This commit is contained in:
+20
-18
@@ -29,21 +29,22 @@ var (
|
|||||||
func New(rootCtx context.Context, ds model.DataStore, cw artwork.CacheWarmer, broker events.Broker,
|
func New(rootCtx context.Context, ds model.DataStore, cw artwork.CacheWarmer, broker events.Broker,
|
||||||
pls core.Playlists, m metrics.Metrics) model.Scanner {
|
pls core.Playlists, m metrics.Metrics) model.Scanner {
|
||||||
c := &controller{
|
c := &controller{
|
||||||
rootCtx: rootCtx,
|
rootCtx: rootCtx,
|
||||||
ds: ds,
|
ds: ds,
|
||||||
cw: cw,
|
cw: cw,
|
||||||
broker: broker,
|
broker: broker,
|
||||||
pls: pls,
|
pls: pls,
|
||||||
metrics: m,
|
metrics: m,
|
||||||
|
devExternalScanner: conf.Server.DevExternalScanner,
|
||||||
}
|
}
|
||||||
if !conf.Server.DevExternalScanner {
|
if !c.devExternalScanner {
|
||||||
c.limiter = P(rate.Sometimes{Interval: conf.Server.DevActivityPanelUpdateRate})
|
c.limiter = P(rate.Sometimes{Interval: conf.Server.DevActivityPanelUpdateRate})
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *controller) getScanner() scanner {
|
func (s *controller) getScanner() scanner {
|
||||||
if conf.Server.DevExternalScanner {
|
if s.devExternalScanner {
|
||||||
return &scannerExternal{}
|
return &scannerExternal{}
|
||||||
}
|
}
|
||||||
return &scannerImpl{ds: s.ds, cw: s.cw, pls: s.pls}
|
return &scannerImpl{ds: s.ds, cw: s.cw, pls: s.pls}
|
||||||
@@ -92,16 +93,17 @@ type scanner interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type controller struct {
|
type controller struct {
|
||||||
rootCtx context.Context
|
rootCtx context.Context
|
||||||
ds model.DataStore
|
ds model.DataStore
|
||||||
cw artwork.CacheWarmer
|
cw artwork.CacheWarmer
|
||||||
broker events.Broker
|
broker events.Broker
|
||||||
metrics metrics.Metrics
|
metrics metrics.Metrics
|
||||||
pls core.Playlists
|
pls core.Playlists
|
||||||
limiter *rate.Sometimes
|
limiter *rate.Sometimes
|
||||||
count atomic.Uint32
|
devExternalScanner bool
|
||||||
folderCount atomic.Uint32
|
count atomic.Uint32
|
||||||
changesDetected bool
|
folderCount atomic.Uint32
|
||||||
|
changesDetected bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// getLastScanTime returns the most recent scan time across all libraries
|
// getLastScanTime returns the most recent scan time across all libraries
|
||||||
|
|||||||
Reference in New Issue
Block a user