retryer.go (4856B)
1 package aws 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 ) 8 9 // RetryMode provides the mode the API client will use to create a retryer 10 // based on. 11 type RetryMode string 12 13 const ( 14 // RetryModeStandard model provides rate limited retry attempts with 15 // exponential backoff delay. 16 RetryModeStandard RetryMode = "standard" 17 18 // RetryModeAdaptive model provides attempt send rate limiting on throttle 19 // responses in addition to standard mode's retry rate limiting. 20 // 21 // Adaptive retry mode is experimental and is subject to change in the 22 // future. 23 RetryModeAdaptive RetryMode = "adaptive" 24 ) 25 26 // ParseRetryMode attempts to parse a RetryMode from the given string. 27 // Returning error if the value is not a known RetryMode. 28 func ParseRetryMode(v string) (mode RetryMode, err error) { 29 switch v { 30 case "standard": 31 return RetryModeStandard, nil 32 case "adaptive": 33 return RetryModeAdaptive, nil 34 default: 35 return mode, fmt.Errorf("unknown RetryMode, %v", v) 36 } 37 } 38 39 func (m RetryMode) String() string { return string(m) } 40 41 // Retryer is an interface to determine if a given error from a 42 // attempt should be retried, and if so what backoff delay to apply. The 43 // default implementation used by most services is the retry package's Standard 44 // type. Which contains basic retry logic using exponential backoff. 45 type Retryer interface { 46 // IsErrorRetryable returns if the failed attempt is retryable. This check 47 // should determine if the error can be retried, or if the error is 48 // terminal. 49 IsErrorRetryable(error) bool 50 51 // MaxAttempts returns the maximum number of attempts that can be made for 52 // an attempt before failing. A value of 0 implies that the attempt should 53 // be retried until it succeeds if the errors are retryable. 54 MaxAttempts() int 55 56 // RetryDelay returns the delay that should be used before retrying the 57 // attempt. Will return error if the delay could not be determined. 58 RetryDelay(attempt int, opErr error) (time.Duration, error) 59 60 // GetRetryToken attempts to deduct the retry cost from the retry token pool. 61 // Returning the token release function, or error. 62 GetRetryToken(ctx context.Context, opErr error) (releaseToken func(error) error, err error) 63 64 // GetInitialToken returns the initial attempt token that can increment the 65 // retry token pool if the attempt is successful. 66 GetInitialToken() (releaseToken func(error) error) 67 } 68 69 // RetryerV2 is an interface to determine if a given error from an attempt 70 // should be retried, and if so what backoff delay to apply. The default 71 // implementation used by most services is the retry package's Standard type. 72 // Which contains basic retry logic using exponential backoff. 73 // 74 // RetryerV2 replaces the Retryer interface, deprecating the GetInitialToken 75 // method in favor of GetAttemptToken which takes a context, and can return an error. 76 // 77 // The SDK's retry package's Attempt middleware, and utilities will always 78 // wrap a Retryer as a RetryerV2. Delegating to GetInitialToken, only if 79 // GetAttemptToken is not implemented. 80 type RetryerV2 interface { 81 Retryer 82 83 // GetInitialToken returns the initial attempt token that can increment the 84 // retry token pool if the attempt is successful. 85 // 86 // Deprecated: This method does not provide a way to block using Context, 87 // nor can it return an error. Use RetryerV2, and GetAttemptToken instead. 88 GetInitialToken() (releaseToken func(error) error) 89 90 // GetAttemptToken returns the send token that can be used to rate limit 91 // attempt calls. Will be used by the SDK's retry package's Attempt 92 // middleware to get a send token prior to calling the temp and releasing 93 // the send token after the attempt has been made. 94 GetAttemptToken(context.Context) (func(error) error, error) 95 } 96 97 // NopRetryer provides a RequestRetryDecider implementation that will flag 98 // all attempt errors as not retryable, with a max attempts of 1. 99 type NopRetryer struct{} 100 101 // IsErrorRetryable returns false for all error values. 102 func (NopRetryer) IsErrorRetryable(error) bool { return false } 103 104 // MaxAttempts always returns 1 for the original attempt. 105 func (NopRetryer) MaxAttempts() int { return 1 } 106 107 // RetryDelay is not valid for the NopRetryer. Will always return error. 108 func (NopRetryer) RetryDelay(int, error) (time.Duration, error) { 109 return 0, fmt.Errorf("not retrying any attempt errors") 110 } 111 112 // GetRetryToken returns a stub function that does nothing. 113 func (NopRetryer) GetRetryToken(context.Context, error) (func(error) error, error) { 114 return nopReleaseToken, nil 115 } 116 117 // GetInitialToken returns a stub function that does nothing. 118 func (NopRetryer) GetInitialToken() func(error) error { 119 return nopReleaseToken 120 } 121 122 // GetAttemptToken returns a stub function that does nothing. 123 func (NopRetryer) GetAttemptToken(context.Context) (func(error) error, error) { 124 return nopReleaseToken, nil 125 } 126 127 func nopReleaseToken(error) error { return nil }