From 08d9834e2cb1ec37275d7c3b2ec7f32f0ce56d24 Mon Sep 17 00:00:00 2001 From: FiniteReality Date: Mon, 18 May 2020 18:01:23 +0100 Subject: [PATCH] fix: Ensure resetAt is in the future If the current reset time is in the past, then somebody else in the current bucket must have made a request before we were able to. To prevent accidental ratelimits, we fall-back to the second sleep branch, as if the reset time wasn't specified at all. Additionally Extracts the minimum sleep time to a constant, and also bumps it to 750ms. --- src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs b/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs index 09a12ee11..771923cd4 100644 --- a/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs +++ b/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs @@ -13,6 +13,8 @@ namespace Discord.Net.Queue { internal class RequestBucket { + private const int MinimumSleepTimeMs = 750; + private readonly object _lock; private readonly RequestQueue _queue; private int _semaphore; @@ -183,10 +185,11 @@ namespace Discord.Net.Queue ThrowRetryLimit(request); - if (resetAt.HasValue) + if (resetAt.HasValue && resetAt > DateTimeOffset.UtcNow) { if (resetAt > timeoutAt) ThrowRetryLimit(request); + int millis = (int)Math.Ceiling((resetAt.Value - DateTimeOffset.UtcNow).TotalMilliseconds); #if DEBUG_LIMITS Debug.WriteLine($"[{id}] Sleeping {millis} ms (Pre-emptive)"); @@ -196,12 +199,12 @@ namespace Discord.Net.Queue } else { - if ((timeoutAt.Value - DateTimeOffset.UtcNow).TotalMilliseconds < 500.0) + if ((timeoutAt.Value - DateTimeOffset.UtcNow).TotalMilliseconds < MinimumSleepTimeMs) ThrowRetryLimit(request); #if DEBUG_LIMITS - Debug.WriteLine($"[{id}] Sleeping 500* ms (Pre-emptive)"); + Debug.WriteLine($"[{id}] Sleeping {MinimumSleepTimeMs}* ms (Pre-emptive)"); #endif - await Task.Delay(500, request.Options.CancelToken).ConfigureAwait(false); + await Task.Delay(MinimumSleepTimeMs, request.Options.CancelToken).ConfigureAwait(false); } continue; }