aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go')
-rw-r--r--vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go76
1 files changed, 48 insertions, 28 deletions
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
index e25a460..a397b0d 100644
--- a/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
+++ b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
@@ -1,11 +1,11 @@
package client
import (
- "math/rand"
- "sync"
+ "strconv"
"time"
"github.com/aws/aws-sdk-go/aws/request"
+ "github.com/aws/aws-sdk-go/internal/sdkrand"
)
// DefaultRetryer implements basic retry logic using exponential backoff for
@@ -30,25 +30,27 @@ func (d DefaultRetryer) MaxRetries() int {
return d.NumMaxRetries
}
-var seededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())})
-
// RetryRules returns the delay duration before retrying this request again
func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
// Set the upper limit of delay in retrying at ~five minutes
minTime := 30
throttle := d.shouldThrottle(r)
if throttle {
+ if delay, ok := getRetryDelay(r); ok {
+ return delay
+ }
+
minTime = 500
}
retryCount := r.RetryCount
- if retryCount > 13 {
- retryCount = 13
- } else if throttle && retryCount > 8 {
+ if throttle && retryCount > 8 {
retryCount = 8
+ } else if retryCount > 13 {
+ retryCount = 13
}
- delay := (1 << uint(retryCount)) * (seededRand.Intn(minTime) + minTime)
+ delay := (1 << uint(retryCount)) * (sdkrand.SeededRand.Intn(minTime) + minTime)
return time.Duration(delay) * time.Millisecond
}
@@ -60,7 +62,7 @@ func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
return *r.Retryable
}
- if r.HTTPResponse.StatusCode >= 500 {
+ if r.HTTPResponse.StatusCode >= 500 && r.HTTPResponse.StatusCode != 501 {
return true
}
return r.IsErrorRetryable() || d.shouldThrottle(r)
@@ -68,29 +70,47 @@ func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
// ShouldThrottle returns true if the request should be throttled.
func (d DefaultRetryer) shouldThrottle(r *request.Request) bool {
- if r.HTTPResponse.StatusCode == 502 ||
- r.HTTPResponse.StatusCode == 503 ||
- r.HTTPResponse.StatusCode == 504 {
- return true
+ switch r.HTTPResponse.StatusCode {
+ case 429:
+ case 502:
+ case 503:
+ case 504:
+ default:
+ return r.IsErrorThrottle()
}
- return r.IsErrorThrottle()
-}
-// lockedSource is a thread-safe implementation of rand.Source
-type lockedSource struct {
- lk sync.Mutex
- src rand.Source
+ return true
}
-func (r *lockedSource) Int63() (n int64) {
- r.lk.Lock()
- n = r.src.Int63()
- r.lk.Unlock()
- return
+// This will look in the Retry-After header, RFC 7231, for how long
+// it will wait before attempting another request
+func getRetryDelay(r *request.Request) (time.Duration, bool) {
+ if !canUseRetryAfterHeader(r) {
+ return 0, false
+ }
+
+ delayStr := r.HTTPResponse.Header.Get("Retry-After")
+ if len(delayStr) == 0 {
+ return 0, false
+ }
+
+ delay, err := strconv.Atoi(delayStr)
+ if err != nil {
+ return 0, false
+ }
+
+ return time.Duration(delay) * time.Second, true
}
-func (r *lockedSource) Seed(seed int64) {
- r.lk.Lock()
- r.src.Seed(seed)
- r.lk.Unlock()
+// Will look at the status code to see if the retry header pertains to
+// the status code.
+func canUseRetryAfterHeader(r *request.Request) bool {
+ switch r.HTTPResponse.StatusCode {
+ case 429:
+ case 503:
+ default:
+ return false
+ }
+
+ return true
}