Skip to content

Commit 72757af

Browse files
committed
Add retry logic to querier
1 parent 7c98fee commit 72757af

File tree

2 files changed

+43
-8
lines changed

2 files changed

+43
-8
lines changed

supertokens/constants.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,5 @@ var (
3030
const DashboardVersion = "0.7"
3131

3232
const DefaultTenantId string = "public"
33+
34+
const RateLimitStatusCode = 429

supertokens/querier.go

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"net/http"
2525
"strings"
2626
"sync"
27+
"time"
2728
)
2829

2930
type Querier struct {
@@ -61,7 +62,7 @@ func (q *Querier) GetQuerierAPIVersion() (string, error) {
6162
}
6263
client := &http.Client{}
6364
return client.Do(req)
64-
}, len(QuerierHosts))
65+
}, len(QuerierHosts), nil)
6566

6667
if err != nil {
6768
return "", err
@@ -141,7 +142,7 @@ func (q *Querier) SendPostRequest(path string, data map[string]interface{}) (map
141142

142143
client := &http.Client{}
143144
return client.Do(req)
144-
}, len(QuerierHosts))
145+
}, len(QuerierHosts), nil)
145146
}
146147

147148
func (q *Querier) SendDeleteRequest(path string, data map[string]interface{}, params map[string]string) (map[string]interface{}, error) {
@@ -182,7 +183,7 @@ func (q *Querier) SendDeleteRequest(path string, data map[string]interface{}, pa
182183

183184
client := &http.Client{}
184185
return client.Do(req)
185-
}, len(QuerierHosts))
186+
}, len(QuerierHosts), nil)
186187
}
187188

188189
func (q *Querier) SendGetRequest(path string, params map[string]string) (map[string]interface{}, error) {
@@ -217,7 +218,7 @@ func (q *Querier) SendGetRequest(path string, params map[string]string) (map[str
217218

218219
client := &http.Client{}
219220
return client.Do(req)
220-
}, len(QuerierHosts))
221+
}, len(QuerierHosts), nil)
221222
}
222223

223224
func (q *Querier) SendPutRequest(path string, data map[string]interface{}) (map[string]interface{}, error) {
@@ -251,7 +252,7 @@ func (q *Querier) SendPutRequest(path string, data map[string]interface{}) (map[
251252

252253
client := &http.Client{}
253254
return client.Do(req)
254-
}, len(QuerierHosts))
255+
}, len(QuerierHosts), nil)
255256
}
256257

257258
type httpRequestFunction func(url string) (*http.Response, error)
@@ -274,22 +275,39 @@ func GetAllCoreUrlsForPath(path string) []string {
274275
return result
275276
}
276277

277-
func (q *Querier) sendRequestHelper(path NormalisedURLPath, httpRequest httpRequestFunction, numberOfTries int) (map[string]interface{}, error) {
278+
func (q *Querier) sendRequestHelper(path NormalisedURLPath, httpRequest httpRequestFunction, numberOfTries int, retryInfoMap *map[string]int) (map[string]interface{}, error) {
278279
if numberOfTries == 0 {
279280
return nil, errors.New("no SuperTokens core available to query")
280281
}
281282

282283
querierHostLock.Lock()
283284
currentDomain := QuerierHosts[querierLastTriedIndex].Domain.GetAsStringDangerous()
284285
currentBasePath := QuerierHosts[querierLastTriedIndex].BasePath.GetAsStringDangerous()
286+
url := currentDomain + currentBasePath + path.GetAsStringDangerous()
287+
288+
maxRetries := 5
289+
var _retryInfoMap map[string]int
290+
291+
if retryInfoMap != nil {
292+
_retryInfoMap = *retryInfoMap
293+
} else {
294+
_retryInfoMap = map[string]int{}
295+
}
296+
297+
_, ok := _retryInfoMap[url]
298+
299+
if !ok {
300+
_retryInfoMap[url] = maxRetries
301+
}
302+
285303
querierLastTriedIndex = (querierLastTriedIndex + 1) % len(QuerierHosts)
286304
querierHostLock.Unlock()
287305

288-
resp, err := httpRequest(currentDomain + currentBasePath + path.GetAsStringDangerous())
306+
resp, err := httpRequest(url)
289307

290308
if err != nil {
291309
if strings.Contains(err.Error(), "connection refused") {
292-
return q.sendRequestHelper(path, httpRequest, numberOfTries-1)
310+
return q.sendRequestHelper(path, httpRequest, numberOfTries-1, &_retryInfoMap)
293311
}
294312
if resp != nil {
295313
resp.Body.Close()
@@ -304,6 +322,21 @@ func (q *Querier) sendRequestHelper(path NormalisedURLPath, httpRequest httpRequ
304322
return nil, readErr
305323
}
306324
if resp.StatusCode != 200 {
325+
if resp.StatusCode == RateLimitStatusCode {
326+
retriesLeft := _retryInfoMap[url]
327+
328+
if retriesLeft > 0 {
329+
_retryInfoMap[url] = retriesLeft - 1
330+
331+
attemptsMade := maxRetries - retriesLeft
332+
delay := 10 + (250 * attemptsMade)
333+
334+
time.Sleep(time.Millisecond * time.Duration(delay))
335+
336+
return q.sendRequestHelper(path, httpRequest, numberOfTries, &_retryInfoMap)
337+
}
338+
}
339+
307340
return nil, fmt.Errorf("SuperTokens core threw an error for a request to path: '%s' with status code: %v and message: %s", path.GetAsStringDangerous(), resp.StatusCode, body)
308341
}
309342

0 commit comments

Comments
 (0)