hashicorp / go-retryablehttp

Retryable HTTP client in Go
Mozilla Public License 2.0
1.99k stars 251 forks source link

Could you add 429 Too Many Request as default policy for retry #99

Closed mariotoffia closed 4 years ago

mariotoffia commented 4 years ago

Hi, the HTTP code [429 Too Many Requests]() is a retryable http error where it may be possible to parse out the Retry-After: {{num}} [time resolution] response header element. I've implemented it like this but it would be nice if it could be placed into the standard policy as well as default backoff?

Cheers, Mario :)

func (ep *ClimatixICEndpoint) newClient() *retryablehttp.Client {
    client := retryablehttp.NewClient()

    client.Backoff = func(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration {
        if resp.StatusCode == 429 {
                        if s, ok := resp.Header["Retry-After"]; ok {
                if sleep, err := strconv.ParseInt(s[0], 10, 32); err == nil {
                    return time.Duration(int64(time.Second) * sleep)
                }
            }
        }

        return retryablehttp.DefaultBackoff(min, max, attemptNum, resp)
    }

    client.CheckRetry = func(c context.Context, resp *http.Response, err error) (bool, error) {
        if resp.StatusCode == 429 {
            return true, nil
        }
        // All other go to default policy
        return retryablehttp.DefaultRetryPolicy(c, resp, err)
    }

    return client
}
jefferai commented 4 years ago

I think it'd be interesting to have this functionality but could you PR it?

mariotoffia commented 4 years ago

@jefferai I've added the code and one test that passes locally on my computer. I've never used circle ci and do not understand which test case that do not pass (stating three run and one failing).