rate limit: make context aware (#731)

* rate limits: Make context aware

* binance: rate limit allow for cancellation of reservation when deadline is exceeded

* request: add context.done() before initiating any bulk work.

* binance: update error return for rate limiting

* request: updated dealine check to remove after time.Now procedure as this will obfuscate a deadline which will be limited by the context check on every attempt, so no need to sleep with delay.
This commit is contained in:
Ryan O'Hara-Reid
2021-08-10 12:08:27 +10:00
committed by GitHub
parent 4602ade809
commit 232d6ebc1f
18 changed files with 245 additions and 198 deletions

View File

@@ -112,10 +112,17 @@ func (i *Item) validateRequest(ctx context.Context, r *Requester) (*http.Request
// DoRequest performs a HTTP/HTTPS request with the supplied params
func (r *Requester) doRequest(ctx context.Context, endpoint EndpointLimit, newRequest Generate) error {
for attempt := 1; ; attempt++ {
// Check if context has finished before executing new attempt.
select {
case <-ctx.Done():
return ctx.Err()
default:
}
// Initiate a rate limit reservation and sleep on requested endpoint
err := r.InitiateRateLimit(endpoint)
err := r.InitiateRateLimit(ctx, endpoint)
if err != nil {
return err
return fmt.Errorf("failed to rate limit HTTP request: %w", err)
}
p, err := newRequest()
@@ -162,7 +169,7 @@ func (r *Requester) doRequest(ctx context.Context, endpoint EndpointLimit, newRe
delay = after
}
if d, ok := req.Context().Deadline(); ok && d.After(time.Now()) && time.Now().Add(delay).After(d) {
if dl, ok := req.Context().Deadline(); ok && dl.Before(time.Now().Add(delay)) {
if err != nil {
return fmt.Errorf("deadline would be exceeded by retry, err: %v", err)
}