]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blame - vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
Initial transfer of provider code
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / aws / aws-sdk-go / aws / client / default_retryer.go
CommitLineData
bae9f6d2
JC
1package client
2
3import (
4 "math/rand"
5 "sync"
6 "time"
7
8 "github.com/aws/aws-sdk-go/aws/request"
9)
10
11// DefaultRetryer implements basic retry logic using exponential backoff for
12// most services. If you want to implement custom retry logic, implement the
13// request.Retryer interface or create a structure type that composes this
14// struct and override the specific methods. For example, to override only
15// the MaxRetries method:
16//
17// type retryer struct {
18// service.DefaultRetryer
19// }
20//
21// // This implementation always has 100 max retries
22// func (d retryer) MaxRetries() uint { return 100 }
23type DefaultRetryer struct {
24 NumMaxRetries int
25}
26
27// MaxRetries returns the number of maximum returns the service will use to make
28// an individual API request.
29func (d DefaultRetryer) MaxRetries() int {
30 return d.NumMaxRetries
31}
32
33var seededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())})
34
35// RetryRules returns the delay duration before retrying this request again
36func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
37 // Set the upper limit of delay in retrying at ~five minutes
38 minTime := 30
39 throttle := d.shouldThrottle(r)
40 if throttle {
41 minTime = 500
42 }
43
44 retryCount := r.RetryCount
45 if retryCount > 13 {
46 retryCount = 13
47 } else if throttle && retryCount > 8 {
48 retryCount = 8
49 }
50
51 delay := (1 << uint(retryCount)) * (seededRand.Intn(minTime) + minTime)
52 return time.Duration(delay) * time.Millisecond
53}
54
55// ShouldRetry returns true if the request should be retried.
56func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
57 // If one of the other handlers already set the retry state
58 // we don't want to override it based on the service's state
59 if r.Retryable != nil {
60 return *r.Retryable
61 }
62
63 if r.HTTPResponse.StatusCode >= 500 {
64 return true
65 }
66 return r.IsErrorRetryable() || d.shouldThrottle(r)
67}
68
69// ShouldThrottle returns true if the request should be throttled.
70func (d DefaultRetryer) shouldThrottle(r *request.Request) bool {
71 if r.HTTPResponse.StatusCode == 502 ||
72 r.HTTPResponse.StatusCode == 503 ||
73 r.HTTPResponse.StatusCode == 504 {
74 return true
75 }
76 return r.IsErrorThrottle()
77}
78
79// lockedSource is a thread-safe implementation of rand.Source
80type lockedSource struct {
81 lk sync.Mutex
82 src rand.Source
83}
84
85func (r *lockedSource) Int63() (n int64) {
86 r.lk.Lock()
87 n = r.src.Int63()
88 r.lk.Unlock()
89 return
90}
91
92func (r *lockedSource) Seed(seed int64) {
93 r.lk.Lock()
94 r.src.Seed(seed)
95 r.lk.Unlock()
96}