]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go
7af81de2aecde518190b1cc8a46c96ae01014460
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / aws / aws-sdk-go / aws / request / retryer.go
1 package request
2
3 import (
4 "time"
5
6 "github.com/aws/aws-sdk-go/aws"
7 "github.com/aws/aws-sdk-go/aws/awserr"
8 )
9
10 // Retryer is an interface to control retry logic for a given service.
11 // The default implementation used by most services is the service.DefaultRetryer
12 // structure, which contains basic retry logic using exponential backoff.
13 type Retryer interface {
14 RetryRules(*Request) time.Duration
15 ShouldRetry(*Request) bool
16 MaxRetries() int
17 }
18
19 // WithRetryer sets a config Retryer value to the given Config returning it
20 // for chaining.
21 func WithRetryer(cfg *aws.Config, retryer Retryer) *aws.Config {
22 cfg.Retryer = retryer
23 return cfg
24 }
25
26 // retryableCodes is a collection of service response codes which are retry-able
27 // without any further action.
28 var retryableCodes = map[string]struct{}{
29 "RequestError": {},
30 "RequestTimeout": {},
31 ErrCodeResponseTimeout: {},
32 "RequestTimeoutException": {}, // Glacier's flavor of RequestTimeout
33 }
34
35 var throttleCodes = map[string]struct{}{
36 "ProvisionedThroughputExceededException": {},
37 "Throttling": {},
38 "ThrottlingException": {},
39 "RequestLimitExceeded": {},
40 "RequestThrottled": {},
41 "LimitExceededException": {}, // Deleting 10+ DynamoDb tables at once
42 "TooManyRequestsException": {}, // Lambda functions
43 "PriorRequestNotComplete": {}, // Route53
44 }
45
46 // credsExpiredCodes is a collection of error codes which signify the credentials
47 // need to be refreshed. Expired tokens require refreshing of credentials, and
48 // resigning before the request can be retried.
49 var credsExpiredCodes = map[string]struct{}{
50 "ExpiredToken": {},
51 "ExpiredTokenException": {},
52 "RequestExpired": {}, // EC2 Only
53 }
54
55 func isCodeThrottle(code string) bool {
56 _, ok := throttleCodes[code]
57 return ok
58 }
59
60 func isCodeRetryable(code string) bool {
61 if _, ok := retryableCodes[code]; ok {
62 return true
63 }
64
65 return isCodeExpiredCreds(code)
66 }
67
68 func isCodeExpiredCreds(code string) bool {
69 _, ok := credsExpiredCodes[code]
70 return ok
71 }
72
73 var validParentCodes = map[string]struct{}{
74 ErrCodeSerialization: struct{}{},
75 ErrCodeRead: struct{}{},
76 }
77
78 func isNestedErrorRetryable(parentErr awserr.Error) bool {
79 if parentErr == nil {
80 return false
81 }
82
83 if _, ok := validParentCodes[parentErr.Code()]; !ok {
84 return false
85 }
86
87 err := parentErr.OrigErr()
88 if err == nil {
89 return false
90 }
91
92 if aerr, ok := err.(awserr.Error); ok {
93 return isCodeRetryable(aerr.Code())
94 }
95
96 return isErrConnectionReset(err)
97 }
98
99 // IsErrorRetryable returns whether the error is retryable, based on its Code.
100 // Returns false if error is nil.
101 func IsErrorRetryable(err error) bool {
102 if err != nil {
103 if aerr, ok := err.(awserr.Error); ok {
104 return isCodeRetryable(aerr.Code()) || isNestedErrorRetryable(aerr)
105 }
106 }
107 return false
108 }
109
110 // IsErrorThrottle returns whether the error is to be throttled based on its code.
111 // Returns false if error is nil.
112 func IsErrorThrottle(err error) bool {
113 if err != nil {
114 if aerr, ok := err.(awserr.Error); ok {
115 return isCodeThrottle(aerr.Code())
116 }
117 }
118 return false
119 }
120
121 // IsErrorExpiredCreds returns whether the error code is a credential expiry error.
122 // Returns false if error is nil.
123 func IsErrorExpiredCreds(err error) bool {
124 if err != nil {
125 if aerr, ok := err.(awserr.Error); ok {
126 return isCodeExpiredCreds(aerr.Code())
127 }
128 }
129 return false
130 }
131
132 // IsErrorRetryable returns whether the error is retryable, based on its Code.
133 // Returns false if the request has no Error set.
134 //
135 // Alias for the utility function IsErrorRetryable
136 func (r *Request) IsErrorRetryable() bool {
137 return IsErrorRetryable(r.Error)
138 }
139
140 // IsErrorThrottle returns whether the error is to be throttled based on its code.
141 // Returns false if the request has no Error set
142 //
143 // Alias for the utility function IsErrorThrottle
144 func (r *Request) IsErrorThrottle() bool {
145 return IsErrorThrottle(r.Error)
146 }
147
148 // IsErrorExpired returns whether the error code is a credential expiry error.
149 // Returns false if the request has no Error set.
150 //
151 // Alias for the utility function IsErrorExpiredCreds
152 func (r *Request) IsErrorExpired() bool {
153 return IsErrorExpiredCreds(r.Error)
154 }