Browse Source

General bugfixes

pull/1546/head
SubZero0 5 years ago
parent
commit
1af6b03c27
3 changed files with 38 additions and 22 deletions
  1. +1
    -1
      src/Discord.Net.Core/Net/BucketId.cs
  2. +0
    -1
      src/Discord.Net.Rest/DiscordRestApiClient.cs
  3. +37
    -20
      src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs

+ 1
- 1
src/Discord.Net.Core/Net/BucketId.cs View File

@@ -51,7 +51,7 @@ namespace Discord.Net
/// <param name="majorParams">Major parameters of the route of this endpoint.</param> /// <param name="majorParams">Major parameters of the route of this endpoint.</param>
/// <returns> /// <returns>
/// A <see cref="BucketId"/> based on the <see cref="HttpMethod"/> /// A <see cref="BucketId"/> based on the <see cref="HttpMethod"/>
/// and the <see cref="Endpoint"> with the provided data.
/// and the <see cref="Endpoint"/> with the provided data.
/// </returns> /// </returns>
public static BucketId Create(string httpMethod, string endpoint, Dictionary<string, string> majorParams) public static BucketId Create(string httpMethod, string endpoint, Dictionary<string, string> majorParams)
{ {


+ 0
- 1
src/Discord.Net.Rest/DiscordRestApiClient.cs View File

@@ -1490,7 +1490,6 @@ namespace Discord.API
private static BucketId GetBucketId(string httpMethod, BucketIds ids, Expression<Func<string>> endpointExpr, string callingMethod) private static BucketId GetBucketId(string httpMethod, BucketIds ids, Expression<Func<string>> endpointExpr, string callingMethod)
{ {
ids.HttpMethod ??= httpMethod; ids.HttpMethod ??= httpMethod;
Debug.WriteLine("GetBucketId: " + CreateBucketId(endpointExpr)(ids));
return _bucketIdGenerators.GetOrAdd(callingMethod, x => CreateBucketId(endpointExpr))(ids); return _bucketIdGenerators.GetOrAdd(callingMethod, x => CreateBucketId(endpointExpr))(ids);
} }




+ 37
- 20
src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs View File

@@ -33,7 +33,7 @@ namespace Discord.Net.Queue
_lock = new object(); _lock = new object();


if (request.Options.IsClientBucket) if (request.Options.IsClientBucket)
WindowCount = ClientBucket.Get(request.Options.BucketId).WindowCount;
WindowCount = ClientBucket.Get(Id).WindowCount;
else else
WindowCount = 1; //Only allow one request until we get a header back WindowCount = 1; //Only allow one request until we get a header back
_semaphore = WindowCount; _semaphore = WindowCount;
@@ -181,7 +181,8 @@ namespace Discord.Net.Queue
} }


DateTimeOffset? timeoutAt = request.TimeoutAt; DateTimeOffset? timeoutAt = request.TimeoutAt;
if (windowCount > 0 && Interlocked.Decrement(ref _semaphore) < 0)
int semaphore = 0;
if (windowCount > 0 && (semaphore = Interlocked.Decrement(ref _semaphore)) < 0)
{ {
if (!isRateLimited) if (!isRateLimited)
{ {
@@ -216,7 +217,7 @@ namespace Discord.Net.Queue
} }
#if DEBUG_LIMITS #if DEBUG_LIMITS
else else
Debug.WriteLine($"[{id}] Entered Semaphore ({_semaphore}/{WindowCount} remaining)");
Debug.WriteLine($"[{id}] Entered Semaphore ({semaphore}/{WindowCount} remaining)");
#endif #endif
break; break;
} }
@@ -230,31 +231,47 @@ namespace Discord.Net.Queue
lock (_lock) lock (_lock)
{ {
if (redirected) if (redirected)
Interlocked.Decrement(ref _semaphore); //we might still hit a real ratelimit if all tickets were already taken, can't do much about it since we didn't know they were the same
bool hasQueuedReset = _resetTick != null;
if (info.Limit.HasValue && WindowCount != info.Limit.Value)
{ {
WindowCount = info.Limit.Value;
_semaphore = info.Remaining.Value;
Interlocked.Decrement(ref _semaphore); //we might still hit a real ratelimit if all tickets were already taken, can't do much about it since we didn't know they were the same
#if DEBUG_LIMITS #if DEBUG_LIMITS
Debug.WriteLine($"[{id}] Upgraded Semaphore to {info.Remaining.Value}/{WindowCount}");
Debug.WriteLine($"[{id}] Decrease Semaphore");
#endif #endif
} }
bool hasQueuedReset = _resetTick != null;


if (info.Bucket != null && !redirected) if (info.Bucket != null && !redirected)
{ {
(RequestBucket, BucketId) hashBucket = _queue.UpdateBucketHash(request.Options.BucketId, info.Bucket);
if (hashBucket.Item1 is null || hashBucket.Item2 is null)
return;
if (hashBucket.Item1 == this) //this bucket got promoted to a hash queue
Id = hashBucket.Item2;
else
(RequestBucket, BucketId) hashBucket = _queue.UpdateBucketHash(Id, info.Bucket);
if (!(hashBucket.Item1 is null) && !(hashBucket.Item2 is null))
{ {
_redirectBucket = hashBucket.Item1; //this request should be part of another bucket, this bucket will be disabled, redirect everything
_redirectBucket.UpdateRateLimit(id, request, info, is429, redirected: true); //update the hash bucket ratelimit
if (hashBucket.Item1 == this) //this bucket got promoted to a hash queue
{
Id = hashBucket.Item2;
#if DEBUG_LIMITS
Debug.WriteLine($"[{id}] Promoted to Hash Bucket ({hashBucket.Item2})");
#endif
}
else
{
_redirectBucket = hashBucket.Item1; //this request should be part of another bucket, this bucket will be disabled, redirect everything
_redirectBucket.UpdateRateLimit(id, request, info, is429, redirected: true); //update the hash bucket ratelimit
#if DEBUG_LIMITS
Debug.WriteLine($"[{id}] Redirected to {_redirectBucket.Id}");
#endif
return;
}
} }
} }


if (info.Limit.HasValue && WindowCount != info.Limit.Value)
{
WindowCount = info.Limit.Value;
_semaphore = info.Remaining.Value;
#if DEBUG_LIMITS
Debug.WriteLine($"[{id}] Upgraded Semaphore to {info.Remaining.Value}/{WindowCount}");
#endif
}

DateTimeOffset? resetTick = null; DateTimeOffset? resetTick = null;


//Using X-RateLimit-Remaining causes a race condition //Using X-RateLimit-Remaining causes a race condition
@@ -289,11 +306,11 @@ namespace Discord.Net.Queue
Debug.WriteLine($"[{id}] X-RateLimit-Reset: {info.Reset.Value.ToUnixTimeSeconds()} ({diff} ms, {info.Lag?.TotalMilliseconds} ms lag)"); Debug.WriteLine($"[{id}] X-RateLimit-Reset: {info.Reset.Value.ToUnixTimeSeconds()} ({diff} ms, {info.Lag?.TotalMilliseconds} ms lag)");
#endif #endif
} }
else if (request.Options.IsClientBucket && request.Options.BucketId != null)
else if (request.Options.IsClientBucket && Id != null)
{ {
resetTick = DateTimeOffset.UtcNow.AddSeconds(ClientBucket.Get(request.Options.BucketId).WindowSeconds);
resetTick = DateTimeOffset.UtcNow.AddSeconds(ClientBucket.Get(Id).WindowSeconds);
#if DEBUG_LIMITS #if DEBUG_LIMITS
Debug.WriteLine($"[{id}] Client Bucket ({ClientBucket.Get(request.Options.BucketId).WindowSeconds * 1000} ms)");
Debug.WriteLine($"[{id}] Client Bucket ({ClientBucket.Get(Id).WindowSeconds * 1000} ms)");
#endif #endif
} }




Loading…
Cancel
Save