forked from TrueCloudLab/restic
retry: Do not retry Stat() if file does not exist
In non test/debug code, Stat() is used exclusively to check whether a file exists. Thus, do not retry if a file is reported as not existing.
This commit is contained in:
parent
40ac678252
commit
648edeca40
2 changed files with 30 additions and 0 deletions
|
@ -139,6 +139,10 @@ func (be *Backend) Stat(ctx context.Context, h restic.Handle) (fi restic.FileInf
|
||||||
var innerError error
|
var innerError error
|
||||||
fi, innerError = be.Backend.Stat(ctx, h)
|
fi, innerError = be.Backend.Stat(ctx, h)
|
||||||
|
|
||||||
|
if be.Backend.IsNotExist(innerError) {
|
||||||
|
// do not retry if file is not found, as stat is usually used to check whether a file exists
|
||||||
|
return backoff.Permanent(innerError)
|
||||||
|
}
|
||||||
return innerError
|
return innerError
|
||||||
})
|
})
|
||||||
return fi, err
|
return fi, err
|
||||||
|
|
|
@ -274,6 +274,32 @@ func TestBackendLoadRetry(t *testing.T) {
|
||||||
test.Equals(t, 2, attempt)
|
test.Equals(t, 2, attempt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBackendStatNotExists(t *testing.T) {
|
||||||
|
// stat should not retry if the error matches IsNotExist
|
||||||
|
notFound := errors.New("not found")
|
||||||
|
attempt := 0
|
||||||
|
|
||||||
|
be := mock.NewBackend()
|
||||||
|
be.StatFn = func(ctx context.Context, h restic.Handle) (restic.FileInfo, error) {
|
||||||
|
attempt++
|
||||||
|
if attempt > 1 {
|
||||||
|
t.Fail()
|
||||||
|
return restic.FileInfo{}, errors.New("must not retry")
|
||||||
|
}
|
||||||
|
return restic.FileInfo{}, notFound
|
||||||
|
}
|
||||||
|
be.IsNotExistFn = func(err error) bool {
|
||||||
|
return errors.Is(err, notFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
TestFastRetries(t)
|
||||||
|
retryBackend := New(be, 10, nil, nil)
|
||||||
|
|
||||||
|
_, err := retryBackend.Stat(context.TODO(), restic.Handle{})
|
||||||
|
test.Assert(t, be.IsNotExistFn(err), "unexpected error %v", err)
|
||||||
|
test.Equals(t, 1, attempt)
|
||||||
|
}
|
||||||
|
|
||||||
func assertIsCanceled(t *testing.T, err error) {
|
func assertIsCanceled(t *testing.T, err error) {
|
||||||
test.Assert(t, err == context.Canceled, "got unexpected err %v", err)
|
test.Assert(t, err == context.Canceled, "got unexpected err %v", err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue