retry.go (2056B)
1 package retry 2 3 import ( 4 "context" 5 "time" 6 7 "github.com/aws/aws-sdk-go-v2/aws" 8 ) 9 10 // AddWithErrorCodes returns a Retryer with additional error codes considered 11 // for determining if the error should be retried. 12 func AddWithErrorCodes(r aws.Retryer, codes ...string) aws.Retryer { 13 retryable := &RetryableErrorCode{ 14 Codes: map[string]struct{}{}, 15 } 16 for _, c := range codes { 17 retryable.Codes[c] = struct{}{} 18 } 19 20 return &withIsErrorRetryable{ 21 RetryerV2: wrapAsRetryerV2(r), 22 Retryable: retryable, 23 } 24 } 25 26 type withIsErrorRetryable struct { 27 aws.RetryerV2 28 Retryable IsErrorRetryable 29 } 30 31 func (r *withIsErrorRetryable) IsErrorRetryable(err error) bool { 32 if v := r.Retryable.IsErrorRetryable(err); v != aws.UnknownTernary { 33 return v.Bool() 34 } 35 return r.RetryerV2.IsErrorRetryable(err) 36 } 37 38 // AddWithMaxAttempts returns a Retryer with MaxAttempts set to the value 39 // specified. 40 func AddWithMaxAttempts(r aws.Retryer, max int) aws.Retryer { 41 return &withMaxAttempts{ 42 RetryerV2: wrapAsRetryerV2(r), 43 Max: max, 44 } 45 } 46 47 type withMaxAttempts struct { 48 aws.RetryerV2 49 Max int 50 } 51 52 func (w *withMaxAttempts) MaxAttempts() int { 53 return w.Max 54 } 55 56 // AddWithMaxBackoffDelay returns a retryer wrapping the passed in retryer 57 // overriding the RetryDelay behavior for a alternate minimum initial backoff 58 // delay. 59 func AddWithMaxBackoffDelay(r aws.Retryer, delay time.Duration) aws.Retryer { 60 return &withMaxBackoffDelay{ 61 RetryerV2: wrapAsRetryerV2(r), 62 backoff: NewExponentialJitterBackoff(delay), 63 } 64 } 65 66 type withMaxBackoffDelay struct { 67 aws.RetryerV2 68 backoff *ExponentialJitterBackoff 69 } 70 71 func (r *withMaxBackoffDelay) RetryDelay(attempt int, err error) (time.Duration, error) { 72 return r.backoff.BackoffDelay(attempt, err) 73 } 74 75 type wrappedAsRetryerV2 struct { 76 aws.Retryer 77 } 78 79 func wrapAsRetryerV2(r aws.Retryer) aws.RetryerV2 { 80 v, ok := r.(aws.RetryerV2) 81 if !ok { 82 v = wrappedAsRetryerV2{Retryer: r} 83 } 84 85 return v 86 } 87 88 func (w wrappedAsRetryerV2) GetAttemptToken(context.Context) (func(error) error, error) { 89 return w.Retryer.GetInitialToken(), nil 90 }