exchanges/request: abstract and consolidate rate limiting code to request package (#1477)

* initial consolidation of rate limiting code to request package to reduce bespoke code implementation

* continued

* finish abstraction

* lint

* exchanges: fix tests

* linter: fix

* poloniex: fix auth rate limit not being set

* ratelimiter: convert from token to weight

* glorious: nits addressed with fire

* linter: rip

* change func name set -> get

* fix test

* derbit: impl

---------

Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io>
This commit is contained in:
Ryan O'Hara-Reid
2024-06-03 11:57:31 +10:00
committed by GitHub
parent aeb4a87913
commit f6a95da536
64 changed files with 780 additions and 2577 deletions

View File

@@ -300,7 +300,7 @@ func (b *Bitflyer) SendHTTPRequest(ctx context.Context, ep exchange.URL, path st
HTTPDebugging: b.HTTPDebugging,
HTTPRecording: b.HTTPRecording,
}
return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) {
return b.SendPayload(ctx, request.UnAuth, func() (*request.Item, error) {
return item, nil
}, request.UnauthenticatedRequest)
}

View File

@@ -74,7 +74,7 @@ func (b *Bitflyer) SetDefaults() {
b.Requester, err = request.New(b.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
request.WithLimiter(GetRateLimit()))
if err != nil {
log.Errorln(log.ExchangeSys, err)
}

View File

@@ -1,11 +1,9 @@
package bitflyer
import (
"context"
"time"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"golang.org/x/time/rate"
)
// Exchange specific rate limit consts
@@ -17,50 +15,14 @@ const (
bitflyerPublicRequestRate = 500
)
// RateLimit implements the rate.Limiter interface
type RateLimit struct {
Auth *rate.Limiter
UnAuth *rate.Limiter
// Send a New Order
// Submit New Parent Order (Special order)
// Cancel All Orders
Order *rate.Limiter
LowVolume *rate.Limiter
}
// Limit limits outbound requests
func (r *RateLimit) Limit(ctx context.Context, f request.EndpointLimit) error {
switch f {
case request.Auth:
return r.Auth.Wait(ctx)
case orders:
err := r.Auth.Wait(ctx)
if err != nil {
return err
}
return r.Order.Wait(ctx)
case lowVolume:
err := r.LowVolume.Wait(ctx)
if err != nil {
return err
}
err = r.Order.Wait(ctx)
if err != nil {
return err
}
return r.Auth.Wait(ctx)
default:
return r.UnAuth.Wait(ctx)
}
}
// SetRateLimit returns the rate limit for the exchange
func SetRateLimit() *RateLimit {
return &RateLimit{
Auth: request.NewRateLimit(biflyerRateInterval, bitflyerPrivateRequestRate),
UnAuth: request.NewRateLimit(biflyerRateInterval, bitflyerPublicRequestRate),
Order: request.NewRateLimit(biflyerRateInterval, bitflyerPrivateSendOrderRequestRate),
LowVolume: request.NewRateLimit(time.Minute, bitflyerPrivateLowVolumeRequestRate),
// GetRateLimit returns the rate limit for the exchange
func GetRateLimit() request.RateLimitDefinitions {
return request.RateLimitDefinitions{
request.Auth: request.NewRateLimitWithWeight(biflyerRateInterval, bitflyerPrivateRequestRate, 1),
request.UnAuth: request.NewRateLimitWithWeight(biflyerRateInterval, bitflyerPublicRequestRate, 1),
// TODO: Below limits need to also take from auth rate limit. This
// can not yet be tested and verified so is left not done for now.
orders: request.NewRateLimitWithWeight(biflyerRateInterval, bitflyerPrivateSendOrderRequestRate, 1),
lowVolume: request.NewRateLimitWithWeight(time.Minute, bitflyerPrivateLowVolumeRequestRate, 1),
}
}