forked from TrueCloudLab/restic
retrybackend: Fail operations when context is already canceled
Depending on the used backend, operations started with a canceled context may fail or not. For example the local backend still works in large parts when called with a canceled context. Backends transfering data via http don't work. It is also not possible to retry failed operations in that state as the RetryBackend will abort with a 'context canceled' error. Ensure uniform behavior of all backends by checking for a canceled context by checking for a canceled context as a first step in the RetryBackend. This ensures uniform behavior across all backends, as backends are always wrapped in a RetryBackend.
This commit is contained in:
parent
fc60b560ba
commit
e483b63c40
1 changed files with 10 additions and 0 deletions
|
@ -33,6 +33,16 @@ func NewRetryBackend(be restic.Backend, maxTries int, report func(string, error,
|
|||
}
|
||||
|
||||
func (be *RetryBackend) retry(ctx context.Context, msg string, f func() error) error {
|
||||
// Don't do anything when called with an already cancelled context. There would be
|
||||
// no retries in that case either, so be consistent and abort always.
|
||||
// This enforces a strict contract for backend methods: Using a cancelled context
|
||||
// will prevent any backup repository modifications. This simplifies ensuring that
|
||||
// a backup repository is not modified any further after a context was cancelled.
|
||||
// The 'local' backend for example does not provide this guarantee on its own.
|
||||
if ctx.Err() != nil {
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
err := backoff.RetryNotify(f,
|
||||
backoff.WithContext(backoff.WithMaxRetries(backoff.NewExponentialBackOff(), uint64(be.MaxTries)), ctx),
|
||||
func(err error, d time.Duration) {
|
||||
|
|
Loading…
Reference in a new issue