From 9d38e1d578140be909a56e9d936ac1ea1308648e Mon Sep 17 00:00:00 2001 From: Anders Brams Date: Thu, 8 Aug 2024 22:57:59 +0200 Subject: [PATCH] Exponential backoff on HTTP 429 --- http.go | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/http.go b/http.go index 7c2cfba..1b7b1ea 100644 --- a/http.go +++ b/http.go @@ -1,16 +1,23 @@ package hjem -import "net/http" +import ( + "math" + "net/http" + "time" +) var DefaultClient http.Client func init() { DefaultClient = http.Client{ - Transport: &DefaultHeadersTripper{ - next: http.DefaultTransport, - headers: map[string]string{ - "User-Agent": "tpanum/hjem (github.com/tpanum/hjem)", + Transport: &RetryRoundTripper{ + next: &DefaultHeadersTripper{ + next: http.DefaultTransport, + headers: map[string]string{ + "User-Agent": "tpanum/hjem (github.com/tpanum/hjem)", + }, }, + maxRetries: 5, }, } } @@ -27,3 +34,33 @@ func (t *DefaultHeadersTripper) RoundTrip(req *http.Request) (*http.Response, er return t.next.RoundTrip(req) } + +type RetryRoundTripper struct { + next http.RoundTripper + maxRetries int +} + +func (r *RetryRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + var resp *http.Response + var err error + + for i := 0; i <= r.maxRetries; i++ { + resp, err = r.next.RoundTrip(req) + + if err != nil { + return nil, err + } + + if resp.StatusCode != 429 { + return resp, nil + } + + baseWait := 9 * time.Second + backoff := time.Duration(math.Pow(2, float64(i))) * time.Second + wait := baseWait + backoff + + time.Sleep(wait) + } + + return resp, err +}