Fix excessive retries missing --max-duration timeout - fixes #4504

This change checks the context whenever rclone might retry, and
doesn't retry if the current context has an error.

This fixes the pathological behaviour of `--max-duration` refusing to
exit because all the context deadline exceeded errors were being
retried.

This unfortunately meant changing the shouldRetry logic in every
backend and doing a lot of context propagation.

See: https://forum.rclone.org/t/add-flag-to-exit-immediately-when-max-duration-reached/22723
This commit is contained in:
Nick Craig-Wood
2021-03-11 14:44:01 +00:00
parent 32925dae1f
commit 4013bc4a4c
31 changed files with 474 additions and 360 deletions

View File

@@ -1,6 +1,7 @@
package fserrors
import (
"context"
"fmt"
"io"
"net"
@@ -170,3 +171,21 @@ func TestRetryAfter(t *testing.T) {
assert.True(t, IsRetryAfterError(err))
assert.Contains(t, e.Error(), "try again after")
}
func TestContextError(t *testing.T) {
var err = io.EOF
ctx, cancel := context.WithCancel(context.Background())
assert.False(t, ContextError(ctx, &err))
assert.Equal(t, io.EOF, err)
cancel()
assert.True(t, ContextError(ctx, &err))
assert.Equal(t, io.EOF, err)
err = nil
assert.True(t, ContextError(ctx, &err))
assert.Equal(t, context.Canceled, err)
}