From 780af98e1e023ec7edbd3b0006056b08c062d564 Mon Sep 17 00:00:00 2001 From: Philipp Wolfer Date: Thu, 23 Nov 2023 10:49:40 +0100 Subject: [PATCH] Spotify: consider rate limit HTTP headers --- backends/spotify/client.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/backends/spotify/client.go b/backends/spotify/client.go index a164dcc..93fa17f 100644 --- a/backends/spotify/client.go +++ b/backends/spotify/client.go @@ -25,6 +25,7 @@ package spotify import ( "context" "errors" + "net/http" "strconv" "time" @@ -34,6 +35,7 @@ import ( const baseURL = "https://api.spotify.com/v1/" const MaxItemsPerGet = 50 +const DefaultRateLimitWaitSeconds = 5 type Client struct { HttpClient *resty.Client @@ -46,6 +48,24 @@ func NewClient(token oauth2.TokenSource) Client { client.SetBaseURL(baseURL) client.SetHeader("Accept", "application/json") client.SetRetryCount(5) + client.AddRetryCondition( + func(r *resty.Response, err error) bool { + code := r.StatusCode() + return code == http.StatusTooManyRequests || code >= http.StatusInternalServerError + }, + ) + client.SetRetryMaxWaitTime(time.Duration(1 * time.Minute)) + client.SetRetryAfter(func(client *resty.Client, resp *resty.Response) (time.Duration, error) { + var err error + var retryAfter int = DefaultRateLimitWaitSeconds + if resp.StatusCode() == http.StatusTooManyRequests { + retryAfter, err = strconv.Atoi(resp.Header().Get("Retry-After")) + if err != nil { + retryAfter = DefaultRateLimitWaitSeconds + } + } + return time.Duration(retryAfter * int(time.Second)), err + }) return Client{ HttpClient: client, }