mirror of
https://github.com/rclone/rclone.git
synced 2026-07-13 01:02:15 -04:00
fs/chunkedreader: fix spurious errors when a parallel stream is closed early
Closing a stream in the parallel chunked reader cancels the stream's context, so the in-flight read returns context.Canceled. This was wrapped and returned as "failed to read stream", which the VFS cache downloader treats as a real download error - it only recognises asyncreader.ErrorStreamAbandoned as a benign teardown, as returned by the sequential reader. Return asyncreader.ErrorStreamAbandoned for a cancellation so tearing down the parallel reader (on close, seek or reposition) is recognised as benign, matching the sequential reader, instead of logging download errors and retrying when --vfs-read-chunk-streams is used with --vfs-cache-mode full.
This commit is contained in:
@@ -2,11 +2,13 @@ package chunkedreader
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/rclone/rclone/fs"
|
||||
"github.com/rclone/rclone/fs/asyncreader"
|
||||
"github.com/rclone/rclone/fs/hash"
|
||||
"github.com/rclone/rclone/fs/log"
|
||||
"github.com/rclone/rclone/fs/operations"
|
||||
@@ -136,6 +138,14 @@ func (s *stream) close() (err error) {
|
||||
if s.rc != nil {
|
||||
orErr(&err, s.rc.Close())
|
||||
}
|
||||
// close cancels the stream's context above, so a cancellation error
|
||||
// just means the stream was intentionally abandoned. Report that as
|
||||
// asyncreader.ErrorStreamAbandoned - the same signal the sequential
|
||||
// reader uses - so callers (e.g. the VFS cache downloader) treat it as
|
||||
// a benign teardown rather than a read failure.
|
||||
if errors.Is(err, context.Canceled) {
|
||||
return asyncreader.ErrorStreamAbandoned
|
||||
}
|
||||
if err != nil && err != io.EOF {
|
||||
return fmt.Errorf("parallel chunked reader: failed to read stream at %d size %d: %w", s.offset, s.size, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user