dropbox: don't retry chunked upload requests when the upload has been cancelled
The append loop retries everything once the upload session has started, so a cancelled context error was retried through all the low level retries with exponential backoff before the upload gave up.
This commit is contained in:
@@ -2106,6 +2106,11 @@ func (o *Object) uploadChunked(ctx context.Context, in0 io.Reader, commitInfo *f
|
||||
}
|
||||
}
|
||||
}
|
||||
// Don't waste the low level retries if the context has
|
||||
// been cancelled
|
||||
if fserrors.ContextError(ctx, &err) {
|
||||
return false, err
|
||||
}
|
||||
return err != nil, err
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -151,6 +151,7 @@ type uploadSessionClient struct {
|
||||
maxAppends int // fail the append after this many calls to stop runaway loops
|
||||
bytesWritten int64 // bytes received by UploadSessionAppendV2Context
|
||||
finishCalled bool // set if UploadSessionFinishContext was called
|
||||
appended func() // if set, called after each successful append
|
||||
}
|
||||
|
||||
var errTooManyAppends = errors.New("too many appends - upload looping?")
|
||||
@@ -173,6 +174,9 @@ func (c *uploadSessionClient) UploadSessionAppendV2Context(ctx context.Context,
|
||||
return err
|
||||
}
|
||||
c.bytesWritten += n
|
||||
if c.appended != nil {
|
||||
c.appended()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -197,6 +201,16 @@ func newUploadTestFs(t *testing.T, srv files.ContextClient, chunkSize fs.SizeSuf
|
||||
return f
|
||||
}
|
||||
|
||||
// endlessReader supplies bytes forever
|
||||
type endlessReader struct{}
|
||||
|
||||
func (endlessReader) Read(p []byte) (int, error) {
|
||||
for i := range p {
|
||||
p[i] = 'x'
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func TestUploadChunkedEarlyEOF(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
@@ -235,6 +249,25 @@ func TestUploadChunkedEarlyEOF(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestUploadChunkedCancel(t *testing.T) {
|
||||
// Cancelling the context must stop the upload even though every
|
||||
// append is succeeding
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
client := &uploadSessionClient{maxAppends: 8}
|
||||
client.appended = func() {
|
||||
if client.appends == 2 {
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
f := newUploadTestFs(t, client, 100)
|
||||
o := &Object{fs: f, remote: "test.bin"}
|
||||
_, err := o.uploadChunked(ctx, endlessReader{}, files.NewCommitInfo("/test.bin"), -1)
|
||||
require.Error(t, err)
|
||||
assert.ErrorIs(t, err, context.Canceled)
|
||||
assert.False(t, client.finishCalled)
|
||||
}
|
||||
|
||||
func (f *Fs) importPaperForTest(t *testing.T) {
|
||||
content := `# test doc
|
||||
|
||||
|
||||
Reference in New Issue
Block a user