fix(scanner): increase watcher channel buffers to prevent dropped filesystem events

When files were moved between libraries, the small channel buffers (size 1)
throughout the watcher pipeline caused backpressure that led to dropped
filesystem events. This meant only some of the affected folders were scanned,
preventing cross-library move detection from working correctly.

Increase all watcher channel buffers to 500 and switch to blocking sends
to ensure no filesystem events are silently dropped.
This commit is contained in:
Deluan
2026-03-12 17:07:34 -04:00
parent d0fbba14ff
commit 0790f66627
3 changed files with 6 additions and 10 deletions
+2 -2
View File
@@ -17,8 +17,8 @@ func (s *localStorage) Start(ctx context.Context) (<-chan string, error) {
if !s.watching.CompareAndSwap(false, true) {
return nil, errors.New("watcher already started")
}
input := make(chan notify.EventInfo, 1)
output := make(chan string, 1)
input := make(chan notify.EventInfo, 500)
output := make(chan string, 500)
started := make(chan struct{})
go func() {
+3 -7
View File
@@ -48,7 +48,7 @@ func GetWatcher(ds model.DataStore, s model.Scanner) Watcher {
ds: ds,
scanner: s,
triggerWait: conf.Server.Scanner.WatcherWait,
watcherNotify: make(chan scanNotification, 1),
watcherNotify: make(chan scanNotification, 500),
libraryWatchers: make(map[int]*libraryWatcherInstance),
}
})
@@ -272,12 +272,8 @@ func (w *watcher) processLibraryEvents(ctx context.Context, lib *model.Library,
continue
}
// Notify the main watcher of changes
select {
case w.watcherNotify <- scanNotification{Library: lib, FolderPath: folderPath}:
default:
// Channel is full, notification already pending
}
// Notify the main watcher of changes. This will trigger a scan after the debounce period.
w.watcherNotify <- scanNotification{Library: lib, FolderPath: folderPath}
}
}
}
+1 -1
View File
@@ -27,7 +27,7 @@ var _ = Describe("Watcher", func() {
DeferCleanup(configtest.SetupConfig())
conf.Server.Scanner.WatcherWait = 50 * time.Millisecond // Short wait for tests
ctx, cancel = context.WithCancel(context.Background())
ctx, cancel = context.WithCancel(GinkgoT().Context())
DeferCleanup(cancel)
lib = &model.Library{