diff options
Diffstat (limited to 'vendor/github.com/minio/minio-go/v7/retry.go')
-rw-r--r-- | vendor/github.com/minio/minio-go/v7/retry.go | 148 |
1 files changed, 0 insertions, 148 deletions
diff --git a/vendor/github.com/minio/minio-go/v7/retry.go b/vendor/github.com/minio/minio-go/v7/retry.go deleted file mode 100644 index 1c6105e..0000000 --- a/vendor/github.com/minio/minio-go/v7/retry.go +++ /dev/null | |||
@@ -1,148 +0,0 @@ | |||
1 | /* | ||
2 | * MinIO Go Library for Amazon S3 Compatible Cloud Storage | ||
3 | * Copyright 2015-2017 MinIO, Inc. | ||
4 | * | ||
5 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | * you may not use this file except in compliance with the License. | ||
7 | * You may obtain a copy of the License at | ||
8 | * | ||
9 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | * | ||
11 | * Unless required by applicable law or agreed to in writing, software | ||
12 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | * See the License for the specific language governing permissions and | ||
15 | * limitations under the License. | ||
16 | */ | ||
17 | |||
18 | package minio | ||
19 | |||
20 | import ( | ||
21 | "context" | ||
22 | "crypto/x509" | ||
23 | "errors" | ||
24 | "net/http" | ||
25 | "net/url" | ||
26 | "time" | ||
27 | ) | ||
28 | |||
29 | // MaxRetry is the maximum number of retries before stopping. | ||
30 | var MaxRetry = 10 | ||
31 | |||
32 | // MaxJitter will randomize over the full exponential backoff time | ||
33 | const MaxJitter = 1.0 | ||
34 | |||
35 | // NoJitter disables the use of jitter for randomizing the exponential backoff time | ||
36 | const NoJitter = 0.0 | ||
37 | |||
38 | // DefaultRetryUnit - default unit multiplicative per retry. | ||
39 | // defaults to 200 * time.Millisecond | ||
40 | var DefaultRetryUnit = 200 * time.Millisecond | ||
41 | |||
42 | // DefaultRetryCap - Each retry attempt never waits no longer than | ||
43 | // this maximum time duration. | ||
44 | var DefaultRetryCap = time.Second | ||
45 | |||
46 | // newRetryTimer creates a timer with exponentially increasing | ||
47 | // delays until the maximum retry attempts are reached. | ||
48 | func (c *Client) newRetryTimer(ctx context.Context, maxRetry int, unit, cap time.Duration, jitter float64) <-chan int { | ||
49 | attemptCh := make(chan int) | ||
50 | |||
51 | // computes the exponential backoff duration according to | ||
52 | // https://www.awsarchitectureblog.com/2015/03/backoff.html | ||
53 | exponentialBackoffWait := func(attempt int) time.Duration { | ||
54 | // normalize jitter to the range [0, 1.0] | ||
55 | if jitter < NoJitter { | ||
56 | jitter = NoJitter | ||
57 | } | ||
58 | if jitter > MaxJitter { | ||
59 | jitter = MaxJitter | ||
60 | } | ||
61 | |||
62 | // sleep = random_between(0, min(cap, base * 2 ** attempt)) | ||
63 | sleep := unit * time.Duration(1<<uint(attempt)) | ||
64 | if sleep > cap { | ||
65 | sleep = cap | ||
66 | } | ||
67 | if jitter != NoJitter { | ||
68 | sleep -= time.Duration(c.random.Float64() * float64(sleep) * jitter) | ||
69 | } | ||
70 | return sleep | ||
71 | } | ||
72 | |||
73 | go func() { | ||
74 | defer close(attemptCh) | ||
75 | for i := 0; i < maxRetry; i++ { | ||
76 | select { | ||
77 | case attemptCh <- i + 1: | ||
78 | case <-ctx.Done(): | ||
79 | return | ||
80 | } | ||
81 | |||
82 | select { | ||
83 | case <-time.After(exponentialBackoffWait(i)): | ||
84 | case <-ctx.Done(): | ||
85 | return | ||
86 | } | ||
87 | } | ||
88 | }() | ||
89 | return attemptCh | ||
90 | } | ||
91 | |||
92 | // List of AWS S3 error codes which are retryable. | ||
93 | var retryableS3Codes = map[string]struct{}{ | ||
94 | "RequestError": {}, | ||
95 | "RequestTimeout": {}, | ||
96 | "Throttling": {}, | ||
97 | "ThrottlingException": {}, | ||
98 | "RequestLimitExceeded": {}, | ||
99 | "RequestThrottled": {}, | ||
100 | "InternalError": {}, | ||
101 | "ExpiredToken": {}, | ||
102 | "ExpiredTokenException": {}, | ||
103 | "SlowDown": {}, | ||
104 | // Add more AWS S3 codes here. | ||
105 | } | ||
106 | |||
107 | // isS3CodeRetryable - is s3 error code retryable. | ||
108 | func isS3CodeRetryable(s3Code string) (ok bool) { | ||
109 | _, ok = retryableS3Codes[s3Code] | ||
110 | return ok | ||
111 | } | ||
112 | |||
113 | // List of HTTP status codes which are retryable. | ||
114 | var retryableHTTPStatusCodes = map[int]struct{}{ | ||
115 | 429: {}, // http.StatusTooManyRequests is not part of the Go 1.5 library, yet | ||
116 | 499: {}, // client closed request, retry. A non-standard status code introduced by nginx. | ||
117 | http.StatusInternalServerError: {}, | ||
118 | http.StatusBadGateway: {}, | ||
119 | http.StatusServiceUnavailable: {}, | ||
120 | http.StatusGatewayTimeout: {}, | ||
121 | // Add more HTTP status codes here. | ||
122 | } | ||
123 | |||
124 | // isHTTPStatusRetryable - is HTTP error code retryable. | ||
125 | func isHTTPStatusRetryable(httpStatusCode int) (ok bool) { | ||
126 | _, ok = retryableHTTPStatusCodes[httpStatusCode] | ||
127 | return ok | ||
128 | } | ||
129 | |||
130 | // For now, all http Do() requests are retriable except some well defined errors | ||
131 | func isRequestErrorRetryable(err error) bool { | ||
132 | if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { | ||
133 | return false | ||
134 | } | ||
135 | if ue, ok := err.(*url.Error); ok { | ||
136 | e := ue.Unwrap() | ||
137 | switch e.(type) { | ||
138 | // x509: certificate signed by unknown authority | ||
139 | case x509.UnknownAuthorityError: | ||
140 | return false | ||
141 | } | ||
142 | switch e.Error() { | ||
143 | case "http: server gave HTTP response to HTTPS client": | ||
144 | return false | ||
145 | } | ||
146 | } | ||
147 | return true | ||
148 | } | ||