From 4089811525c93bd7ba2ee9b8e6fb02114913a7ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Skocze=C5=84?= Date: Thu, 13 May 2021 09:24:04 +0200 Subject: [PATCH] Program wide global rate limit --- discord.go | 2 +- ratelimit.go | 19 +++++++++++++++++++ ratelimit_test.go | 17 +++++++++++++++++ restapi.go | 11 +++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/discord.go b/discord.go index 6e312cc76..5d89472f6 100644 --- a/discord.go +++ b/discord.go @@ -21,7 +21,7 @@ import ( ) // VERSION of DiscordGo, follows Semantic Versioning. (http://semver.org/) -const VERSION = "0.2.10-nlp" +const VERSION = "0.2.15-nlp" // ErrMFA will be risen by New when the user has 2FA. var ErrMFA = errors.New("account has 2FA enabled") diff --git a/ratelimit.go b/ratelimit.go index 4c913990c..7d1fa17dc 100644 --- a/ratelimit.go +++ b/ratelimit.go @@ -10,6 +10,25 @@ import ( "time" ) +var ( + GlobalRateLimit = 50 + GlobalRateLimitMutex = sync.Mutex{} + GlobalLimit = false +) + +// Start a program wide rate limit +func StartGlobalLimit() { + GlobalLimit = true + go func (){ + for { + GlobalRateLimitMutex.Lock() + GlobalRateLimit = 50 + GlobalRateLimitMutex.Unlock() + time.Sleep(time.Second) + } + }() +} + // customRateLimit holds information for defining a custom rate limit type customRateLimit struct { suffix string diff --git a/ratelimit_test.go b/ratelimit_test.go index db18211a5..a3a77e118 100644 --- a/ratelimit_test.go +++ b/ratelimit_test.go @@ -7,6 +7,23 @@ import ( "time" ) +func TestGlobalRateLimit(t *testing.T) { + StartGlobalLimit() + b1, _ := New("") + b2, _ := New("") + + _, _ = b1.User("633751371404804107") + _, _ = b2.User("485853402560200704") + if GlobalRateLimit == 50 { + t.Fatal("Global Rate Limit did not decrease!") + } + + time.Sleep(time.Second) + if GlobalRateLimit != 50 { + t.Fatal("Global Rate Limit did not refresh!") + } +} + // This test takes ~2 seconds to run func TestRatelimitReset(t *testing.T) { rl := NewRatelimiter() diff --git a/restapi.go b/restapi.go index d4bdf72d0..321700f7a 100644 --- a/restapi.go +++ b/restapi.go @@ -63,6 +63,17 @@ func (s *Session) RequestWithBucketID(method, urlStr string, data interface{}, b // Sequence is the sequence number, if it fails with a 502 it will // retry with sequence+1 until it either succeeds or sequence >= session.MaxRestRetries func (s *Session) request(method, urlStr, contentType string, b []byte, bucketID string, sequence int) (response []byte, err error) { + if GlobalLimit { + if GlobalRateLimit == 0 { + log.Println("Global Rate Limit depleted! ("+s.Token[:10]+")") // Note: Temp + } + GlobalRateLimitMutex.Lock() + for GlobalRateLimit == 0 { + time.Sleep(time.Millisecond) // Wait for refresh + } + GlobalRateLimit -= 1 + GlobalRateLimitMutex.Unlock() + } if bucketID == "" { bucketID = strings.SplitN(urlStr, "?", 2)[0] }