HTTP Retry With Exponential Backoff
Retry idempotent HTTP requests on server errors and throttling responses, backing off between attempts and honouring context cancellation.
Code
package httpx
import (
"context"
"net/http"
"time"
)
func Retry(ctx context.Context, client *http.Client, req *http.Request, attempts int) (*http.Response, error) {
var lastErr error
delay := 100 * time.Millisecond
for i := 0; i < attempts; i++ {
resp, err := client.Do(req.WithContext(ctx))
if err == nil {
if resp.StatusCode < 500 && resp.StatusCode != http.StatusTooManyRequests {
return resp, nil
}
resp.Body.Close()
} else {
lastErr = err
}
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-time.After(delay):
}
delay *= 2
}
if lastErr != nil {
return nil, lastErr
}
return nil, context.DeadlineExceeded
}Report a problem with this exampleOpens a pre-filled issue on GitHub.