| @@ -12,15 +12,15 @@ namespace Discord.Net.Queue | |||||
| internal struct GatewayBucket | internal struct GatewayBucket | ||||
| { | { | ||||
| private static readonly ImmutableDictionary<GatewayBucketType, GatewayBucket> DefsByType; | private static readonly ImmutableDictionary<GatewayBucketType, GatewayBucket> DefsByType; | ||||
| private static readonly ImmutableDictionary<string, GatewayBucket> DefsById; | |||||
| private static readonly ImmutableDictionary<BucketId, GatewayBucket> DefsById; | |||||
| static GatewayBucket() | static GatewayBucket() | ||||
| { | { | ||||
| var buckets = new[] | var buckets = new[] | ||||
| { | { | ||||
| new GatewayBucket(GatewayBucketType.Unbucketed, "<gateway-unbucketed>", 120, 60), | |||||
| new GatewayBucket(GatewayBucketType.Identify, "<gateway-identify>", 1, 5), | |||||
| new GatewayBucket(GatewayBucketType.PresenceUpdate, "<gateway-presenceupdate>", 5, 60), | |||||
| new GatewayBucket(GatewayBucketType.Unbucketed, BucketId.Create(null, "<gateway-unbucketed>", null), 120, 60), | |||||
| new GatewayBucket(GatewayBucketType.Identify, BucketId.Create(null, "<gateway-identify>", null), 1, 5), | |||||
| new GatewayBucket(GatewayBucketType.PresenceUpdate, BucketId.Create(null, "<gateway-presenceupdate>", null), 5, 60), | |||||
| }; | }; | ||||
| var builder = ImmutableDictionary.CreateBuilder<GatewayBucketType, GatewayBucket>(); | var builder = ImmutableDictionary.CreateBuilder<GatewayBucketType, GatewayBucket>(); | ||||
| @@ -28,21 +28,21 @@ namespace Discord.Net.Queue | |||||
| builder.Add(bucket.Type, bucket); | builder.Add(bucket.Type, bucket); | ||||
| DefsByType = builder.ToImmutable(); | DefsByType = builder.ToImmutable(); | ||||
| var builder2 = ImmutableDictionary.CreateBuilder<string, GatewayBucket>(); | |||||
| var builder2 = ImmutableDictionary.CreateBuilder<BucketId, GatewayBucket>(); | |||||
| foreach (var bucket in buckets) | foreach (var bucket in buckets) | ||||
| builder2.Add(bucket.Id, bucket); | builder2.Add(bucket.Id, bucket); | ||||
| DefsById = builder2.ToImmutable(); | DefsById = builder2.ToImmutable(); | ||||
| } | } | ||||
| public static GatewayBucket Get(GatewayBucketType type) => DefsByType[type]; | public static GatewayBucket Get(GatewayBucketType type) => DefsByType[type]; | ||||
| public static GatewayBucket Get(string id) => DefsById[id]; | |||||
| public static GatewayBucket Get(BucketId id) => DefsById[id]; | |||||
| public GatewayBucketType Type { get; } | public GatewayBucketType Type { get; } | ||||
| public string Id { get; } | |||||
| public BucketId Id { get; } | |||||
| public int WindowCount { get; set; } | public int WindowCount { get; set; } | ||||
| public int WindowSeconds { get; set; } | public int WindowSeconds { get; set; } | ||||
| public GatewayBucket(GatewayBucketType type, string id, int count, int seconds) | |||||
| public GatewayBucket(GatewayBucketType type, BucketId id, int count, int seconds) | |||||
| { | { | ||||
| Type = type; | Type = type; | ||||
| Id = id; | Id = id; | ||||
| @@ -110,7 +110,7 @@ namespace Discord.Net.Queue | |||||
| else | else | ||||
| request.Options.CancelToken = _requestCancelToken; | request.Options.CancelToken = _requestCancelToken; | ||||
| var bucket = GetOrCreateBucket(request.Options.BucketId, request); | |||||
| var bucket = GetOrCreateBucket(request.Options, request); | |||||
| await bucket.SendAsync(request).ConfigureAwait(false); | await bucket.SendAsync(request).ConfigureAwait(false); | ||||
| createdTokenSource?.Dispose(); | createdTokenSource?.Dispose(); | ||||
| } | } | ||||
| @@ -163,7 +163,7 @@ namespace Discord.Net.Queue | |||||
| var options = RequestOptions.CreateOrClone(request.Options); | var options = RequestOptions.CreateOrClone(request.Options); | ||||
| options.BucketId = globalBucketType.Id; | options.BucketId = globalBucketType.Id; | ||||
| var globalRequest = new WebSocketRequest(null, null, false, options); | var globalRequest = new WebSocketRequest(null, null, false, options); | ||||
| var globalBucket = GetOrCreateBucket(globalBucketType.Id, globalRequest); | |||||
| var globalBucket = GetOrCreateBucket(options, globalRequest); | |||||
| await globalBucket.TriggerAsync(id, globalRequest); | await globalBucket.TriggerAsync(id, globalRequest); | ||||
| } | } | ||||
| internal void ReleaseIdentifySemaphore(int id) | internal void ReleaseIdentifySemaphore(int id) | ||||
| @@ -179,7 +179,7 @@ namespace Discord.Net.Queue | |||||
| #endif | #endif | ||||
| } | } | ||||
| private RequestBucket GetOrCreateBucket(string id, IRequest request) | |||||
| private RequestBucket GetOrCreateBucket(RequestOptions options, IRequest request) | |||||
| { | { | ||||
| var bucketId = options.BucketId; | var bucketId = options.BucketId; | ||||
| object obj = _buckets.GetOrAdd(bucketId, x => new RequestBucket(this, request, x)); | object obj = _buckets.GetOrAdd(bucketId, x => new RequestBucket(this, request, x)); | ||||
| @@ -25,7 +25,7 @@ namespace Discord.Net.Queue | |||||
| public int WindowCount { get; private set; } | public int WindowCount { get; private set; } | ||||
| public DateTimeOffset LastAttemptAt { get; private set; } | public DateTimeOffset LastAttemptAt { get; private set; } | ||||
| public RequestBucket(RequestQueue queue, IRequest request, string id) | |||||
| public RequestBucket(RequestQueue queue, IRequest request, BucketId id) | |||||
| { | { | ||||
| _queue = queue; | _queue = queue; | ||||
| Id = id; | Id = id; | ||||
| @@ -285,7 +285,7 @@ namespace Discord.Net.Queue | |||||
| } | } | ||||
| } | } | ||||
| private void UpdateRateLimit(int id, IRequest request, RateLimitInfo info, bool is429) | |||||
| private void UpdateRateLimit(int id, IRequest request, RateLimitInfo info, bool is429, bool redirected = false) | |||||
| { | { | ||||
| if (WindowCount == 0) | if (WindowCount == 0) | ||||
| return; | return; | ||||
| @@ -208,7 +208,7 @@ namespace Discord.API | |||||
| bytes = Encoding.UTF8.GetBytes(SerializeJson(payload)); | bytes = Encoding.UTF8.GetBytes(SerializeJson(payload)); | ||||
| options.IsGatewayBucket = true; | options.IsGatewayBucket = true; | ||||
| if (string.IsNullOrEmpty(options.BucketId)) | |||||
| if (options.BucketId == null) | |||||
| options.BucketId = GatewayBucket.Get(GatewayBucketType.Unbucketed).Id; | options.BucketId = GatewayBucket.Get(GatewayBucketType.Unbucketed).Id; | ||||
| await RequestQueue.SendAsync(new WebSocketRequest(WebSocketClient, bytes, true, options)).ConfigureAwait(false); | await RequestQueue.SendAsync(new WebSocketRequest(WebSocketClient, bytes, true, options)).ConfigureAwait(false); | ||||
| await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false); | await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false); | ||||