fix(server): throttle events sent to UI when scanning. Relates to #1511
See also: https://github.com/navidrome/navidrome/issues/1186#issuecomment-1554818537
This commit is contained in:
@@ -51,6 +51,7 @@ require (
|
|||||||
golang.org/x/image v0.20.0
|
golang.org/x/image v0.20.0
|
||||||
golang.org/x/sync v0.8.0
|
golang.org/x/sync v0.8.0
|
||||||
golang.org/x/text v0.18.0
|
golang.org/x/text v0.18.0
|
||||||
|
golang.org/x/time v0.6.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
|||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
|
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||||
|
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
|||||||
+9
-5
@@ -13,6 +13,7 @@ import (
|
|||||||
"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/singleton"
|
"github.com/navidrome/navidrome/utils/singleton"
|
||||||
|
"golang.org/x/time/rate"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Scanner interface {
|
type Scanner interface {
|
||||||
@@ -117,7 +118,8 @@ func (s *scanner) rescan(ctx context.Context, library string, fullRescan bool) e
|
|||||||
func (s *scanner) startProgressTracker(library string) (chan uint32, context.CancelFunc) {
|
func (s *scanner) startProgressTracker(library string) (chan uint32, context.CancelFunc) {
|
||||||
// Must be a new context (not the one passed to the scan method) to allow broadcasting the scan status to all clients
|
// Must be a new context (not the one passed to the scan method) to allow broadcasting the scan status to all clients
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
progress := make(chan uint32, 100)
|
progress := make(chan uint32, 1000)
|
||||||
|
limiter := rate.Sometimes{Every: 10}
|
||||||
go func() {
|
go func() {
|
||||||
s.broker.SendMessage(ctx, &events.ScanStatus{Scanning: true, Count: 0, FolderCount: 0})
|
s.broker.SendMessage(ctx, &events.ScanStatus{Scanning: true, Count: 0, FolderCount: 0})
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -138,10 +140,12 @@ func (s *scanner) startProgressTracker(library string) (chan uint32, context.Can
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
totalFolders, totalFiles := s.incStatusCounter(library, count)
|
totalFolders, totalFiles := s.incStatusCounter(library, count)
|
||||||
s.broker.SendMessage(ctx, &events.ScanStatus{
|
limiter.Do(func() {
|
||||||
Scanning: true,
|
s.broker.SendMessage(ctx, &events.ScanStatus{
|
||||||
Count: int64(totalFiles),
|
Scanning: true,
|
||||||
FolderCount: int64(totalFolders),
|
Count: int64(totalFiles),
|
||||||
|
FolderCount: int64(totalFolders),
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ func (s *TagScanner) Scan(ctx context.Context, lib model.Library, fullScan bool,
|
|||||||
g, walkCtx := errgroup.WithContext(ctx)
|
g, walkCtx := errgroup.WithContext(ctx)
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
for folderStats := range pl.ReadOrDone(walkCtx, foldersFound) {
|
for folderStats := range pl.ReadOrDone(walkCtx, foldersFound) {
|
||||||
progress <- folderStats.AudioFilesCount
|
updateProgress(progress, folderStats.AudioFilesCount)
|
||||||
allFSDirs[folderStats.Path] = folderStats
|
allFSDirs[folderStats.Path] = folderStats
|
||||||
|
|
||||||
if s.folderHasChanged(folderStats, allDBDirs, s.lib.LastScanAt) || fullScan {
|
if s.folderHasChanged(folderStats, allDBDirs, s.lib.LastScanAt) || fullScan {
|
||||||
@@ -185,6 +185,13 @@ func (s *TagScanner) Scan(ctx context.Context, lib model.Library, fullScan bool,
|
|||||||
return s.cnt.total(), err
|
return s.cnt.total(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateProgress(progress chan uint32, count uint32) {
|
||||||
|
select {
|
||||||
|
case progress <- count:
|
||||||
|
default: // It is ok to miss a count update
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func isDirEmpty(ctx context.Context, dir string) (bool, error) {
|
func isDirEmpty(ctx context.Context, dir string) (bool, error) {
|
||||||
children, stats, err := loadDir(ctx, dir)
|
children, stats, err := loadDir(ctx, dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user