fix(watch): remove mutable package var, fix debouncer race

Co-authored-by: Belphemur <197810+Belphemur@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-07-03 13:55:58 +00:00
committed by GitHub
co-authored by Belphemur
parent 69c1a37577
commit 1e692ed19b
+19 -11
View File
@@ -25,10 +25,6 @@ import (
// written (e.g. copied or downloaded into the watched folder). // written (e.g. copied or downloaded into the watched folder).
const debounceDelay = 2 * time.Second const debounceDelay = 2 * time.Second
// watchWorkerCount controls how many optimization jobs can run concurrently
// so the fsnotify event loop is never blocked waiting on a conversion.
var watchWorkerCount = runtime.NumCPU()
func init() { func init() {
if runtime.GOOS != "linux" { if runtime.GOOS != "linux" {
return return
@@ -89,7 +85,9 @@ func WatchCommand(_ *cobra.Command, args []string) error {
} }
}() }()
queue := newOptimizeQueue(watchWorkerCount, &utils2.OptimizeOptions{ // Optimization jobs run in a small worker pool so the fsnotify event loop
// is never blocked waiting on a conversion.
queue := newOptimizeQueue(runtime.NumCPU(), &utils2.OptimizeOptions{
ChapterConverter: chapterConverter, ChapterConverter: chapterConverter,
Quality: quality, Quality: quality,
Override: override, Override: override,
@@ -228,17 +226,27 @@ func (d *eventDebouncer) Trigger(path string) {
d.mu.Lock() d.mu.Lock()
defer d.mu.Unlock() defer d.mu.Unlock()
if timer, exists := d.timers[path]; exists { if existing, exists := d.timers[path]; exists {
timer.Reset(d.delay) existing.Stop()
return
} }
d.timers[path] = time.AfterFunc(d.delay, func() { var timer *time.Timer
timer = time.AfterFunc(d.delay, func() {
d.mu.Lock() d.mu.Lock()
delete(d.timers, path) // Only the still-current timer for this path is allowed to clear the
// entry and fire onQuiet. If Trigger raced with this callback and
// already installed a newer timer, this stale invocation must not
// delete that newer entry or fire early.
owns := d.timers[path] == timer
if owns {
delete(d.timers, path)
}
d.mu.Unlock() d.mu.Unlock()
d.onQuiet(path) if owns {
d.onQuiet(path)
}
}) })
d.timers[path] = timer
} }
// Stop cancels all pending timers. // Stop cancels all pending timers.