From 4be44c4eb23168ef5ace5cf5eb20448f66a30ae0 Mon Sep 17 00:00:00 2001 From: nite Date: Sat, 5 Apr 2025 11:53:00 +1100 Subject: [PATCH] add limiter --- igdb.go | 5 +++++ rate_limiter.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 rate_limiter.go diff --git a/igdb.go b/igdb.go index 634068e..8f3407f 100644 --- a/igdb.go +++ b/igdb.go @@ -11,11 +11,13 @@ type igdb struct { clientID string token *twitchToken flaresolverr *flaresolverr.Flaresolverr + limiter *rateLimiter } func New(clientID, clientSecret string) *igdb { return &igdb{ clientID: clientID, + limiter: newRateLimiter(4), token: NewTwitchToken(clientID, clientSecret), flaresolverr: nil, } @@ -24,12 +26,15 @@ func New(clientID, clientSecret string) *igdb { func NewWithFlaresolverr(clientID, clientSecret string, f *flaresolverr.Flaresolverr) *igdb { return &igdb{ clientID: clientID, + limiter: newRateLimiter(4), token: NewTwitchToken(clientID, clientSecret), flaresolverr: f, } } func (g *igdb) Request(URL string, dataBody any) (*resty.Response, error) { + g.limiter.wait() + t, err := g.token.getToken() if err != nil { return nil, fmt.Errorf("failed to get twitch token: %w", err) diff --git a/rate_limiter.go b/rate_limiter.go new file mode 100644 index 0000000..6bd1b90 --- /dev/null +++ b/rate_limiter.go @@ -0,0 +1,48 @@ +package igdb + +import ( + "sync" + "time" +) + +type rateLimiter struct { + mu sync.Mutex + rate int + interval time.Duration + tokens int + lastRefill time.Time +} + +func newRateLimiter(rate int) *rateLimiter { + return &rateLimiter{ + rate: rate, + interval: time.Second, + tokens: rate, + lastRefill: time.Now(), + } +} + +func (r *rateLimiter) wait() { + r.mu.Lock() + defer r.mu.Unlock() + + now := time.Now() + elapsed := now.Sub(r.lastRefill) + + if elapsed >= r.interval { + r.tokens = r.rate + r.lastRefill = now + } + + if r.tokens <= 0 { + waitTime := r.interval - elapsed + r.mu.Unlock() + time.Sleep(waitTime) + r.mu.Lock() + r.tokens = r.rate - 1 + r.lastRefill = time.Now() + return + } + + r.tokens-- +}