Add option to disable rate-limited request retry (#1151)
* Add option to disable rate-limited request retry Closes #1011. * feat: code review changes Co-authored-by: nitroflap <fe.lap.prog@gmail.com>
This commit is contained in:
parent
2b359776da
commit
c615fc7f19
3 changed files with 27 additions and 6 deletions
|
@ -36,6 +36,7 @@ func New(token string) (s *Session, err error) {
|
||||||
StateEnabled: true,
|
StateEnabled: true,
|
||||||
Compress: true,
|
Compress: true,
|
||||||
ShouldReconnectOnError: true,
|
ShouldReconnectOnError: true,
|
||||||
|
ShouldRetryOnRateLimit: true,
|
||||||
ShardID: 0,
|
ShardID: 0,
|
||||||
ShardCount: 1,
|
ShardCount: 1,
|
||||||
MaxRestRetries: 3,
|
MaxRestRetries: 3,
|
||||||
|
|
17
restapi.go
17
restapi.go
|
@ -73,6 +73,18 @@ func (r RESTError) Error() string {
|
||||||
return "HTTP " + r.Response.Status + ", " + string(r.ResponseBody)
|
return "HTTP " + r.Response.Status + ", " + string(r.ResponseBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RateLimitError is returned when a request exceeds a rate limit
|
||||||
|
// and ShouldRetryOnRateLimit is false. The request may be manually
|
||||||
|
// retried after waiting the duration specified by RetryAfter.
|
||||||
|
type RateLimitError struct {
|
||||||
|
*RateLimit
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error returns a rate limit error with rate limited endpoint and retry time.
|
||||||
|
func (e RateLimitError) Error() string {
|
||||||
|
return "Rate limit exceeded on " + e.URL + ", retry after " + e.RetryAfter.String()
|
||||||
|
}
|
||||||
|
|
||||||
// Request is the same as RequestWithBucketID but the bucket id is the same as the urlStr
|
// Request is the same as RequestWithBucketID but the bucket id is the same as the urlStr
|
||||||
func (s *Session) Request(method, urlStr string, data interface{}) (response []byte, err error) {
|
func (s *Session) Request(method, urlStr string, data interface{}) (response []byte, err error) {
|
||||||
return s.RequestWithBucketID(method, urlStr, data, strings.SplitN(urlStr, "?", 2)[0])
|
return s.RequestWithBucketID(method, urlStr, data, strings.SplitN(urlStr, "?", 2)[0])
|
||||||
|
@ -186,6 +198,8 @@ func (s *Session) RequestWithLockedBucket(method, urlStr, contentType string, b
|
||||||
s.log(LogError, "rate limit unmarshal error, %s", err)
|
s.log(LogError, "rate limit unmarshal error, %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.ShouldRetryOnRateLimit {
|
||||||
s.log(LogInformational, "Rate Limiting %s, retry in %v", urlStr, rl.RetryAfter)
|
s.log(LogInformational, "Rate Limiting %s, retry in %v", urlStr, rl.RetryAfter)
|
||||||
s.handleEvent(rateLimitEventType, &RateLimit{TooManyRequests: &rl, URL: urlStr})
|
s.handleEvent(rateLimitEventType, &RateLimit{TooManyRequests: &rl, URL: urlStr})
|
||||||
|
|
||||||
|
@ -194,6 +208,9 @@ func (s *Session) RequestWithLockedBucket(method, urlStr, contentType string, b
|
||||||
// this method can cause longer delays than required
|
// this method can cause longer delays than required
|
||||||
|
|
||||||
response, err = s.RequestWithLockedBucket(method, urlStr, contentType, b, s.Ratelimiter.LockBucketObject(bucket), sequence)
|
response, err = s.RequestWithLockedBucket(method, urlStr, contentType, b, s.Ratelimiter.LockBucketObject(bucket), sequence)
|
||||||
|
} else {
|
||||||
|
err = &RateLimitError{&RateLimit{TooManyRequests: &rl, URL: urlStr}}
|
||||||
|
}
|
||||||
case http.StatusUnauthorized:
|
case http.StatusUnauthorized:
|
||||||
if strings.Index(s.Token, "Bot ") != 0 {
|
if strings.Index(s.Token, "Bot ") != 0 {
|
||||||
s.log(LogInformational, ErrUnauthorized.Error())
|
s.log(LogInformational, ErrUnauthorized.Error())
|
||||||
|
|
|
@ -43,6 +43,9 @@ type Session struct {
|
||||||
// Should the session reconnect the websocket on errors.
|
// Should the session reconnect the websocket on errors.
|
||||||
ShouldReconnectOnError bool
|
ShouldReconnectOnError bool
|
||||||
|
|
||||||
|
// Should the session retry requests when rate limited.
|
||||||
|
ShouldRetryOnRateLimit bool
|
||||||
|
|
||||||
// Identify is sent during initial handshake with the discord gateway.
|
// Identify is sent during initial handshake with the discord gateway.
|
||||||
// https://discord.com/developers/docs/topics/gateway#identify
|
// https://discord.com/developers/docs/topics/gateway#identify
|
||||||
Identify Identify
|
Identify Identify
|
||||||
|
|
Loading…
Reference in a new issue