mirror of
https://github.com/rclone/rclone.git
synced 2026-05-12 01:57:56 -04:00
vfs/vfscache/downloaders: kick waiters periodically, not just once
The background kicker goroutine had a bare select outside a for loop, so the 5s ticker fired at most once before the goroutine exited. The intent was to run every 5s for the lifetime of the Downloaders. This wraps the select in a for loop so the ticker fires repeatedly until ctx is cancelled. In practice this was benign because every downloader exit and every successful Write already calls kickWaiters, so the background kicker is only load-bearing when a waiter is queued, no downloader is running, and _ensureDownloader failed transiently. In that state, before this fix, the waiter would hang until another Download() call or Close() arrived; now it gets retried every 5s and will either recover or accumulate enough errors to trip maxErrorCount and error out cleanly.
This commit is contained in:
@@ -117,16 +117,18 @@ func New(ctx context.Context, item Item, opt *vfscommon.Options, remote string,
|
||||
}
|
||||
dls.wg.Go(func() {
|
||||
ticker := time.NewTicker(backgroundKickerInterval)
|
||||
select {
|
||||
case <-ticker.C:
|
||||
err := dls.kickWaiters()
|
||||
if err != nil {
|
||||
fs.Errorf(dls.src, "vfs cache: failed to kick waiters: %v", err)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
err := dls.kickWaiters()
|
||||
if err != nil {
|
||||
fs.Errorf(dls.src, "vfs cache: failed to kick waiters: %v", err)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
case <-ctx.Done():
|
||||
break
|
||||
}
|
||||
ticker.Stop()
|
||||
})
|
||||
|
||||
return dls
|
||||
|
||||
Reference in New Issue
Block a user