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

@@ -180,20 +180,18 @@ type GlobalLimitTest struct {
var errEndpointLimitNotFound = errors.New("endpoint limit not found")
func (g *GlobalLimitTest) Limit(e EndpointLimit) error {
func (g *GlobalLimitTest) Limit(ctx context.Context, e EndpointLimit) error {
switch e {
case Auth:
if g.Auth == nil {
return errors.New("auth rate not set")
}
time.Sleep(g.Auth.Reserve().Delay())
return nil
return g.Auth.Wait(ctx)
case UnAuth:
if g.UnAuth == nil {
return errors.New("unauth rate not set")
}
time.Sleep(g.UnAuth.Reserve().Delay())
return nil
return g.UnAuth.Wait(ctx)
default:
return fmt.Errorf("cannot execute functionality: %d %w",
e,
@@ -527,11 +525,24 @@ func TestBasicLimiter(t *testing.T) {
ctx := context.Background()
tn := time.Now()
_ = r.SendPayload(ctx, Unset, func() (*Item, error) { return &i, nil })
_ = r.SendPayload(ctx, Unset, func() (*Item, error) { return &i, nil })
err := r.SendPayload(ctx, Unset, func() (*Item, error) { return &i, nil })
if err != nil {
t.Fatal(err)
}
err = r.SendPayload(ctx, Unset, func() (*Item, error) { return &i, nil })
if err != nil {
t.Fatal(err)
}
if time.Since(tn) < time.Second {
t.Error("rate limit issues")
}
ctx, cancel := context.WithDeadline(ctx, tn.Add(time.Nanosecond))
defer cancel()
err = r.SendPayload(ctx, Unset, func() (*Item, error) { return &i, nil })
if !errors.Is(err, context.DeadlineExceeded) {
t.Fatalf("receieved: %v but expected: %v", err, context.DeadlineExceeded)
}
}
func TestEnableDisableRateLimit(t *testing.T) {