]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blobdiff - vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
deps: github.com/hashicorp/terraform@sdk-v0.11-with-go-modules
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / aws / aws-sdk-go / aws / client / default_retryer.go
index 1313478f2740e7e04064f2e3074a436e56c7e82f..a397b0d044c73a7233235592fe132cca0b60a1c6 100644 (file)
@@ -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
@@ -15,11 +15,11 @@ import (
 // the MaxRetries method:
 //
 //             type retryer struct {
-//      service.DefaultRetryer
+//      client.DefaultRetryer
 //    }
 //
 //    // This implementation always has 100 max retries
-//    func (d retryer) MaxRetries() uint { return 100 }
+//    func (d retryer) MaxRetries() int { return 100 }
 type DefaultRetryer struct {
        NumMaxRetries int
 }
@@ -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
 }