Update go-retryablehttp

This commit is contained in:
Preetha Appan 2017-10-06 13:42:11 -05:00
parent db016a0c8d
commit 10b7ab252f
2 changed files with 23 additions and 14 deletions

View file

@ -107,6 +107,11 @@ type ResponseLogHook func(*log.Logger, *http.Response)
// response body before returning. // response body before returning.
type CheckRetry func(resp *http.Response, err error) (bool, error) type CheckRetry func(resp *http.Response, err error) (bool, error)
// Backoff specifies a policy for how long to wait between retries.
// It is called after a failing request to determine the amount of time
// that should pass before trying again.
type Backoff func(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration
// Client is used to make HTTP requests. It adds additional functionality // Client is used to make HTTP requests. It adds additional functionality
// like automatic retries to tolerate minor outages. // like automatic retries to tolerate minor outages.
type Client struct { type Client struct {
@ -128,6 +133,9 @@ type Client struct {
// CheckRetry specifies the policy for handling retries, and is called // CheckRetry specifies the policy for handling retries, and is called
// after each request. The default policy is DefaultRetryPolicy. // after each request. The default policy is DefaultRetryPolicy.
CheckRetry CheckRetry CheckRetry CheckRetry
// Backoff specifies the policy for how long to wait between retries
Backoff Backoff
} }
// NewClient creates a new Client with default settings. // NewClient creates a new Client with default settings.
@ -139,6 +147,7 @@ func NewClient() *Client {
RetryWaitMax: defaultRetryWaitMax, RetryWaitMax: defaultRetryWaitMax,
RetryMax: defaultRetryMax, RetryMax: defaultRetryMax,
CheckRetry: DefaultRetryPolicy, CheckRetry: DefaultRetryPolicy,
Backoff: DefaultBackoff,
} }
} }
@ -159,6 +168,18 @@ func DefaultRetryPolicy(resp *http.Response, err error) (bool, error) {
return false, nil return false, nil
} }
// DefaultBackoff provides a default callback for Client.Backoff which
// will perform exponential backoff based on the attempt number and limited
// by the provided minimum and maximum durations.
func DefaultBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration {
mult := math.Pow(2, float64(attemptNum)) * float64(min)
sleep := time.Duration(mult)
if float64(sleep) != mult || sleep > max {
sleep = max
}
return sleep
}
// Do wraps calling an HTTP method with retries. // Do wraps calling an HTTP method with retries.
func (c *Client) Do(req *Request) (*http.Response, error) { func (c *Client) Do(req *Request) (*http.Response, error) {
c.Logger.Printf("[DEBUG] %s %s", req.Method, req.URL) c.Logger.Printf("[DEBUG] %s %s", req.Method, req.URL)
@ -211,7 +232,7 @@ func (c *Client) Do(req *Request) (*http.Response, error) {
if remain == 0 { if remain == 0 {
break break
} }
wait := backoff(c.RetryWaitMin, c.RetryWaitMax, i) wait := c.Backoff(c.RetryWaitMin, c.RetryWaitMax, i, resp)
desc := fmt.Sprintf("%s %s", req.Method, req.URL) desc := fmt.Sprintf("%s %s", req.Method, req.URL)
if code > 0 { if code > 0 {
desc = fmt.Sprintf("%s (status: %d)", desc, code) desc = fmt.Sprintf("%s (status: %d)", desc, code)
@ -288,15 +309,3 @@ func PostForm(url string, data url.Values) (*http.Response, error) {
func (c *Client) PostForm(url string, data url.Values) (*http.Response, error) { func (c *Client) PostForm(url string, data url.Values) (*http.Response, error) {
return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
} }
// backoff is used to calculate how long to sleep before retrying
// after observing failures. It takes the minimum/maximum wait time and
// iteration, and returns the duration to wait.
func backoff(min, max time.Duration, iter int) time.Duration {
mult := math.Pow(2, float64(iter)) * float64(min)
sleep := time.Duration(mult)
if float64(sleep) != mult || sleep > max {
sleep = max
}
return sleep
}

2
vendor/vendor.json vendored
View file

@ -34,7 +34,7 @@
{"path":"github.com/hashicorp/go-memdb","checksumSHA1":"T65qvYBTy4rYks7oN+U0muEqtRw=","revision":"2b2d6c35e14e7557ea1003e707d5e179fa315028","revisionTime":"2017-07-25T22:15:03Z"}, {"path":"github.com/hashicorp/go-memdb","checksumSHA1":"T65qvYBTy4rYks7oN+U0muEqtRw=","revision":"2b2d6c35e14e7557ea1003e707d5e179fa315028","revisionTime":"2017-07-25T22:15:03Z"},
{"path":"github.com/hashicorp/go-msgpack/codec","checksumSHA1":"TNlVzNR1OaajcNi3CbQ3bGbaLGU=","revision":"fa3f63826f7c23912c15263591e65d54d080b458","revisionTime":"2015-05-18T23:42:57Z"}, {"path":"github.com/hashicorp/go-msgpack/codec","checksumSHA1":"TNlVzNR1OaajcNi3CbQ3bGbaLGU=","revision":"fa3f63826f7c23912c15263591e65d54d080b458","revisionTime":"2015-05-18T23:42:57Z"},
{"path":"github.com/hashicorp/go-multierror","checksumSHA1":"lrSl49G23l6NhfilxPM0XFs5rZo=","revision":"d30f09973e19c1dfcd120b2d9c4f168e68d6b5d5","revisionTime":"2015-09-16T20:57:42Z"}, {"path":"github.com/hashicorp/go-multierror","checksumSHA1":"lrSl49G23l6NhfilxPM0XFs5rZo=","revision":"d30f09973e19c1dfcd120b2d9c4f168e68d6b5d5","revisionTime":"2015-09-16T20:57:42Z"},
{"path":"github.com/hashicorp/go-retryablehttp","checksumSHA1":"ErJHGU6AVPZM9yoY/xV11TwSjQs=","revision":"6e85be8fee1dcaa02c0eaaac2df5a8fbecf94145","revisionTime":"2016-09-30T03:51:02Z"}, {"path":"github.com/hashicorp/go-retryablehttp","checksumSHA1":"yzoWV7yrS/TvOrKy5ZrdUjsYaOA=","revision":"794af36148bf63c118d6db80eb902a136b907e71","revisionTime":"2017-08-24T18:08:59Z"},
{"path":"github.com/hashicorp/go-rootcerts","checksumSHA1":"A1PcINvF3UiwHRKn8UcgARgvGRs=","revision":"6bb64b370b90e7ef1fa532be9e591a81c3493e00","revisionTime":"2016-05-03T14:34:40Z"}, {"path":"github.com/hashicorp/go-rootcerts","checksumSHA1":"A1PcINvF3UiwHRKn8UcgARgvGRs=","revision":"6bb64b370b90e7ef1fa532be9e591a81c3493e00","revisionTime":"2016-05-03T14:34:40Z"},
{"path":"github.com/hashicorp/go-sockaddr","checksumSHA1":"GP24Vz4EmZAL1ZH2TYTkDiiCO94=","revision":"2d10d7c10258d11196c0ebf2943509e4afd06cd4","revisionTime":"2017-05-23T22:50:28Z"}, {"path":"github.com/hashicorp/go-sockaddr","checksumSHA1":"GP24Vz4EmZAL1ZH2TYTkDiiCO94=","revision":"2d10d7c10258d11196c0ebf2943509e4afd06cd4","revisionTime":"2017-05-23T22:50:28Z"},
{"path":"github.com/hashicorp/go-sockaddr/template","checksumSHA1":"mIUCMmRHslN2bxQZ0uObMnXxk9E=","revision":"2d10d7c10258d11196c0ebf2943509e4afd06cd4","revisionTime":"2017-05-23T22:50:28Z"}, {"path":"github.com/hashicorp/go-sockaddr/template","checksumSHA1":"mIUCMmRHslN2bxQZ0uObMnXxk9E=","revision":"2d10d7c10258d11196c0ebf2943509e4afd06cd4","revisionTime":"2017-05-23T22:50:28Z"},