fserrors: Make a new NoLowLevelRetry error and don't retry them #3777
This commit is contained in:
parent
cb97239a60
commit
572c1079a5
1 changed files with 52 additions and 0 deletions
|
@ -178,6 +178,53 @@ func IsNoRetryError(err error) (isNoRetry bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NoLowLevelRetrier is an optional interface for error as to whether
|
||||||
|
// the operation should not be retried at a low level.
|
||||||
|
//
|
||||||
|
// NoLowLevelRetry errors won't be retried by low level retry loops.
|
||||||
|
type NoLowLevelRetrier interface {
|
||||||
|
error
|
||||||
|
NoLowLevelRetry() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrappedNoLowLevelRetryError is an error wrapped so it will satisfy the
|
||||||
|
// NoLowLevelRetrier interface and return true
|
||||||
|
type wrappedNoLowLevelRetryError struct {
|
||||||
|
error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoLowLevelRetry interface
|
||||||
|
func (err wrappedNoLowLevelRetryError) NoLowLevelRetry() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check interface
|
||||||
|
var _ NoLowLevelRetrier = wrappedNoLowLevelRetryError{error(nil)}
|
||||||
|
|
||||||
|
// NoLowLevelRetryError makes an error which indicates the sync
|
||||||
|
// shouldn't be low level retried.
|
||||||
|
func NoLowLevelRetryError(err error) error {
|
||||||
|
return wrappedNoLowLevelRetryError{err}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cause returns the underlying error
|
||||||
|
func (err wrappedNoLowLevelRetryError) Cause() error {
|
||||||
|
return err.error
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNoLowLevelRetryError returns true if err conforms to the NoLowLevelRetry
|
||||||
|
// interface and calling the NoLowLevelRetry method returns true.
|
||||||
|
func IsNoLowLevelRetryError(err error) (isNoLowLevelRetry bool) {
|
||||||
|
errors.Walk(err, func(err error) bool {
|
||||||
|
if r, ok := err.(NoLowLevelRetrier); ok {
|
||||||
|
isNoLowLevelRetry = r.NoLowLevelRetry()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// RetryAfter is an optional interface for error as to whether the
|
// RetryAfter is an optional interface for error as to whether the
|
||||||
// operation should be retried after a given delay
|
// operation should be retried after a given delay
|
||||||
//
|
//
|
||||||
|
@ -345,6 +392,11 @@ func ShouldRetry(err error) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If error has been marked to NoLowLevelRetry then don't retry
|
||||||
|
if IsNoLowLevelRetryError(err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Find root cause if available
|
// Find root cause if available
|
||||||
retriable, err := Cause(err)
|
retriable, err := Cause(err)
|
||||||
if retriable {
|
if retriable {
|
||||||
|
|
Loading…
Reference in a new issue