Browse Source

fix: Implement correct ratelimit handles for 429's (#2110)

* init

* fix errors
tags/3.3.1
Quin Lynch GitHub 3 years ago
parent
commit
b2598d37b6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 14 deletions
  1. +13
    -3
      src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs
  2. +7
    -11
      src/Discord.Net.Rest/Net/RateLimitInfo.cs

+ 13
- 3
src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs View File

@@ -88,7 +88,7 @@ namespace Discord.Net.Queue
#if DEBUG_LIMITS
Debug.WriteLine($"[{id}] (!) 429");
#endif
UpdateRateLimit(id, request, info, true);
UpdateRateLimit(id, request, info, true, body:response.Stream);
}
await _queue.RaiseRateLimitTriggered(Id, info, $"{request.Method} {request.Endpoint}").ConfigureAwait(false);
continue; //Retry
@@ -316,7 +316,7 @@ namespace Discord.Net.Queue
}
}

private void UpdateRateLimit(int id, IRequest request, RateLimitInfo info, bool is429, bool redirected = false)
private void UpdateRateLimit(int id, IRequest request, RateLimitInfo info, bool is429, bool redirected = false, Stream body = null)
{
if (WindowCount == 0)
return;
@@ -373,7 +373,17 @@ namespace Discord.Net.Queue
Debug.WriteLine($"[{id}] X-RateLimit-Remaining: " + info.Remaining.Value);
_semaphore = info.Remaining.Value;
}*/
if (info.RetryAfter.HasValue)
if (is429)
{
// use the payload reset after value
var payload = info.ReadRatelimitPayload(body);

resetTick = DateTimeOffset.UtcNow.Add(TimeSpan.FromSeconds(payload.RetryAfter));
#if DEBUG_LIMITS
Debug.WriteLine($"[{id}] Reset-After: {info.ResetAfter.Value} ({info.ResetAfter?.TotalMilliseconds} ms)");
#endif
}
else if (info.RetryAfter.HasValue)
{
//RetryAfter is more accurate than Reset, where available
resetTick = DateTimeOffset.UtcNow.AddSeconds(info.RetryAfter.Value);


+ 7
- 11
src/Discord.Net.Rest/Net/RateLimitInfo.cs View File

@@ -61,22 +61,18 @@ namespace Discord.Net
DateTimeOffset.TryParse(temp, CultureInfo.InvariantCulture, DateTimeStyles.None, out var date) ? DateTimeOffset.UtcNow - date : (TimeSpan?)null;
}

internal void ReadRatelimitPayload(Stream response)
internal Ratelimit ReadRatelimitPayload(Stream response)
{
try
if (response != null && response.Length != 0)
{
if (response != null && response.Length != 0)
using (TextReader text = new StreamReader(response))
using (JsonReader reader = new JsonTextReader(text))
{
using (TextReader text = new StreamReader(response))
using (JsonReader reader = new JsonTextReader(text))
{
var ratelimit = Discord.Rest.DiscordRestClient.Serializer.Deserialize<Ratelimit>(reader);

ResetAfter = TimeSpan.FromSeconds(ratelimit.RetryAfter);
}
return Discord.Rest.DiscordRestClient.Serializer.Deserialize<Ratelimit>(reader);
}
}
catch { }

return null;
}
}
}

Loading…
Cancel
Save