mirror of https://github.com/restic/restic.git
retry: explicitly log failed requests
This simplifies finding the request in the log output that cause an operation to fail.
This commit is contained in:
parent
8898f61717
commit
a3633cad9e
|
@ -416,7 +416,11 @@ func OpenRepository(ctx context.Context, opts GlobalOptions) (*repository.Reposi
|
||||||
}
|
}
|
||||||
|
|
||||||
report := func(msg string, err error, d time.Duration) {
|
report := func(msg string, err error, d time.Duration) {
|
||||||
Warnf("%v returned error, retrying after %v: %v\n", msg, d, err)
|
if d >= 0 {
|
||||||
|
Warnf("%v returned error, retrying after %v: %v\n", msg, d, err)
|
||||||
|
} else {
|
||||||
|
Warnf("%v failed: %v\n", msg, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
success := func(msg string, retries int) {
|
success := func(msg string, retries int) {
|
||||||
Warnf("%v operation successful after %d retries\n", msg, retries)
|
Warnf("%v operation successful after %d retries\n", msg, retries)
|
||||||
|
|
|
@ -44,20 +44,28 @@ func New(be backend.Backend, maxTries int, report func(string, error, time.Durat
|
||||||
// retryNotifyErrorWithSuccess is an extension of backoff.RetryNotify with notification of success after an error.
|
// retryNotifyErrorWithSuccess is an extension of backoff.RetryNotify with notification of success after an error.
|
||||||
// success is NOT notified on the first run of operation (only after an error).
|
// success is NOT notified on the first run of operation (only after an error).
|
||||||
func retryNotifyErrorWithSuccess(operation backoff.Operation, b backoff.BackOff, notify backoff.Notify, success func(retries int)) error {
|
func retryNotifyErrorWithSuccess(operation backoff.Operation, b backoff.BackOff, notify backoff.Notify, success func(retries int)) error {
|
||||||
|
var operationWrapper backoff.Operation
|
||||||
if success == nil {
|
if success == nil {
|
||||||
return backoff.RetryNotify(operation, b, notify)
|
operationWrapper = operation
|
||||||
}
|
} else {
|
||||||
retries := 0
|
retries := 0
|
||||||
operationWrapper := func() error {
|
operationWrapper = func() error {
|
||||||
err := operation()
|
err := operation()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
retries++
|
retries++
|
||||||
} else if retries > 0 {
|
} else if retries > 0 {
|
||||||
success(retries)
|
success(retries)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return backoff.RetryNotify(operationWrapper, b, notify)
|
err := backoff.RetryNotify(operationWrapper, b, notify)
|
||||||
|
|
||||||
|
if err != nil && notify != nil {
|
||||||
|
// log final error
|
||||||
|
notify(err, -1)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var fastRetries = false
|
var fastRetries = false
|
||||||
|
|
|
@ -497,3 +497,24 @@ func TestNotifyWithSuccessIsCalled(t *testing.T) {
|
||||||
t.Fatalf("Success should have been called only once, but was called %d times instead", successCalled)
|
t.Fatalf("Success should have been called only once, but was called %d times instead", successCalled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNotifyWithSuccessFinalError(t *testing.T) {
|
||||||
|
operation := func() error {
|
||||||
|
return errors.New("expected error in test")
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyCalled := 0
|
||||||
|
notify := func(error, time.Duration) {
|
||||||
|
notifyCalled++
|
||||||
|
}
|
||||||
|
|
||||||
|
successCalled := 0
|
||||||
|
success := func(retries int) {
|
||||||
|
successCalled++
|
||||||
|
}
|
||||||
|
|
||||||
|
err := retryNotifyErrorWithSuccess(operation, backoff.WithMaxRetries(&backoff.ZeroBackOff{}, 5), notify, success)
|
||||||
|
test.Assert(t, err.Error() == "expected error in test", "wrong error message %v", err)
|
||||||
|
test.Equals(t, 6, notifyCalled, "notify should have been called 6 times")
|
||||||
|
test.Equals(t, 0, successCalled, "success should not have been called")
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue