Browse Source

Share WebSocketRequestQueue between clients

pull/1537/head
Paulo 5 years ago
parent
commit
a6b1633abe
7 changed files with 50 additions and 10 deletions
  1. +2
    -2
      src/Discord.Net.Rest/Net/Queue/GatewayBucket.cs
  2. +10
    -0
      src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs
  3. +1
    -1
      src/Discord.Net.WebSocket/BaseSocketClient.cs
  4. +10
    -1
      src/Discord.Net.WebSocket/DiscordShardedClient.cs
  5. +12
    -1
      src/Discord.Net.WebSocket/DiscordSocketApiClient.cs
  6. +11
    -5
      src/Discord.Net.WebSocket/DiscordSocketClient.cs
  7. +4
    -0
      src/Discord.Net.WebSocket/DiscordSocketConfig.cs

+ 2
- 2
src/Discord.Net.Rest/Net/Queue/GatewayBucket.cs View File

@@ -16,8 +16,8 @@ namespace Discord.Net.Queue
{ {
var buckets = new[] var buckets = new[]
{ {
new GatewayBucket(GatewayBucketType.Unbucketed, "<unbucketed>", 120, 60),
new GatewayBucket(GatewayBucketType.Identify, "<identify>", 1, 5)
new GatewayBucket(GatewayBucketType.Unbucketed, "<gateway-unbucketed>", 120, 60),
new GatewayBucket(GatewayBucketType.Identify, "<gateway-identify>", 1, 5)
}; };


var builder = ImmutableDictionary.CreateBuilder<GatewayBucketType, GatewayBucket>(); var builder = ImmutableDictionary.CreateBuilder<GatewayBucketType, GatewayBucket>();


+ 10
- 0
src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs View File

@@ -332,6 +332,16 @@ namespace Discord.Net.Queue
#if DEBUG_LIMITS #if DEBUG_LIMITS
Debug.WriteLine($"[{id}] Gateway Bucket ({GatewayBucket.Get(request.Options.BucketId).WindowSeconds * 1000} ms)"); Debug.WriteLine($"[{id}] Gateway Bucket ({GatewayBucket.Get(request.Options.BucketId).WindowSeconds * 1000} ms)");
#endif #endif
if (!hasQueuedReset)
{
_resetTick = resetTick;
LastAttemptAt = resetTick.Value;
#if DEBUG_LIMITS
Debug.WriteLine($"[{id}] Reset in {(int)Math.Ceiling((resetTick - DateTimeOffset.UtcNow).Value.TotalMilliseconds)} ms");
#endif
var _ = QueueReset(id, (int)Math.Ceiling((_resetTick.Value - DateTimeOffset.UtcNow).TotalMilliseconds));
}
return;
} }


if (resetTick == null) if (resetTick == null)


+ 1
- 1
src/Discord.Net.WebSocket/BaseSocketClient.cs View File

@@ -80,7 +80,7 @@ namespace Discord.WebSocket
internal BaseSocketClient(DiscordSocketConfig config, DiscordRestApiClient client) internal BaseSocketClient(DiscordSocketConfig config, DiscordRestApiClient client)
: base(config, client) => BaseConfig = config; : base(config, client) => BaseConfig = config;
private static DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config) private static DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config)
=> new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent,
=> new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config._websocketRequestQueue,
rateLimitPrecision: config.RateLimitPrecision, rateLimitPrecision: config.RateLimitPrecision,
useSystemClock: config.UseSystemClock); useSystemClock: config.UseSystemClock);




+ 10
- 1
src/Discord.Net.WebSocket/DiscordShardedClient.cs View File

@@ -6,6 +6,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Threading; using System.Threading;
using Discord.Net.Queue;


namespace Discord.WebSocket namespace Discord.WebSocket
{ {
@@ -83,9 +84,17 @@ namespace Discord.WebSocket
RegisterEvents(_shards[i], i == 0); RegisterEvents(_shards[i], i == 0);
} }
} }

ApiClient.WebSocketRequestQueue.RateLimitTriggered += async (id, info) =>
{
if (info == null)
await _restLogger.VerboseAsync($"Preemptive Rate limit triggered: {id ?? "null"}").ConfigureAwait(false);
else
await _restLogger.WarningAsync($"Rate limit triggered: {id ?? "null"}").ConfigureAwait(false);
};
} }
private static API.DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config) private static API.DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config)
=> new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent,
=> new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config._websocketRequestQueue,
rateLimitPrecision: config.RateLimitPrecision); rateLimitPrecision: config.RateLimitPrecision);


internal override async Task OnLoginAsync(TokenType tokenType, string token) internal override async Task OnLoginAsync(TokenType tokenType, string token)


+ 12
- 1
src/Discord.Net.WebSocket/DiscordSocketApiClient.cs View File

@@ -37,7 +37,17 @@ namespace Discord.API


public ConnectionState ConnectionState { get; private set; } public ConnectionState ConnectionState { get; private set; }


internal RequestQueue WebSocketRequestQueue { get; }

public DiscordSocketApiClient(RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, string userAgent, public DiscordSocketApiClient(RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, string userAgent,
string url = null, RetryMode defaultRetryMode = RetryMode.AlwaysRetry, JsonSerializer serializer = null,
RateLimitPrecision rateLimitPrecision = RateLimitPrecision.Second,
bool useSystemClock = true)
: this(restClientProvider, webSocketProvider, userAgent, null, url, defaultRetryMode, serializer, rateLimitPrecision, useSystemClock)
{
}

internal DiscordSocketApiClient(RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, string userAgent, RequestQueue websocketRequestQueue,
string url = null, RetryMode defaultRetryMode = RetryMode.AlwaysRetry, JsonSerializer serializer = null, string url = null, RetryMode defaultRetryMode = RetryMode.AlwaysRetry, JsonSerializer serializer = null,
RateLimitPrecision rateLimitPrecision = RateLimitPrecision.Second, RateLimitPrecision rateLimitPrecision = RateLimitPrecision.Second,
bool useSystemClock = true) bool useSystemClock = true)
@@ -48,6 +58,7 @@ namespace Discord.API
_isExplicitUrl = true; _isExplicitUrl = true;
WebSocketClient = webSocketProvider(); WebSocketClient = webSocketProvider();
//WebSocketClient.SetHeader("user-agent", DiscordConfig.UserAgent); (Causes issues in .NET Framework 4.6+) //WebSocketClient.SetHeader("user-agent", DiscordConfig.UserAgent); (Causes issues in .NET Framework 4.6+)
WebSocketRequestQueue = websocketRequestQueue ?? new RequestQueue();


WebSocketClient.BinaryMessage += async (data, index, count) => WebSocketClient.BinaryMessage += async (data, index, count) =>
{ {
@@ -208,7 +219,7 @@ namespace Discord.API


options.IsGatewayBucket = true; options.IsGatewayBucket = true;
options.BucketId = GatewayBucket.Get(opCode == GatewayOpCode.Identify ? GatewayBucketType.Identify : GatewayBucketType.Unbucketed).Id; options.BucketId = GatewayBucket.Get(opCode == GatewayOpCode.Identify ? GatewayBucketType.Identify : GatewayBucketType.Unbucketed).Id;
await RequestQueue.SendAsync(new WebSocketRequest(WebSocketClient, bytes, true, options)).ConfigureAwait(false);
await WebSocketRequestQueue.SendAsync(new WebSocketRequest(WebSocketClient, bytes, true, options)).ConfigureAwait(false);
await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false); await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false);
} }




+ 11
- 5
src/Discord.Net.WebSocket/DiscordSocketClient.cs View File

@@ -118,7 +118,16 @@ namespace Discord.WebSocket
/// </summary> /// </summary>
/// <param name="config">The configuration to be used with the client.</param> /// <param name="config">The configuration to be used with the client.</param>
#pragma warning disable IDISP004 #pragma warning disable IDISP004
public DiscordSocketClient(DiscordSocketConfig config) : this(config, CreateApiClient(config), null, null) { }
public DiscordSocketClient(DiscordSocketConfig config) : this(config, CreateApiClient(config), null, null)
{
ApiClient.WebSocketRequestQueue.RateLimitTriggered += async (id, info) =>
{
if (info == null)
await _restLogger.VerboseAsync($"Preemptive Rate limit triggered: {id ?? "null"}").ConfigureAwait(false);
else
await _restLogger.WarningAsync($"Rate limit triggered: {id ?? "null"}").ConfigureAwait(false);
};
}
internal DiscordSocketClient(DiscordSocketConfig config, SemaphoreSlim groupLock, DiscordSocketClient parentClient) : this(config, CreateApiClient(config), groupLock, parentClient) { } internal DiscordSocketClient(DiscordSocketConfig config, SemaphoreSlim groupLock, DiscordSocketClient parentClient) : this(config, CreateApiClient(config), groupLock, parentClient) { }
#pragma warning restore IDISP004 #pragma warning restore IDISP004
private DiscordSocketClient(DiscordSocketConfig config, API.DiscordSocketApiClient client, SemaphoreSlim groupLock, DiscordSocketClient parentClient) private DiscordSocketClient(DiscordSocketConfig config, API.DiscordSocketApiClient client, SemaphoreSlim groupLock, DiscordSocketClient parentClient)
@@ -178,7 +187,7 @@ namespace Discord.WebSocket
_largeGuilds = new ConcurrentQueue<ulong>(); _largeGuilds = new ConcurrentQueue<ulong>();
} }
private static API.DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config) private static API.DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config)
=> new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayHost,
=> new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config._websocketRequestQueue, config.GatewayHost,
rateLimitPrecision: config.RateLimitPrecision); rateLimitPrecision: config.RateLimitPrecision);
/// <inheritdoc /> /// <inheritdoc />
internal override void Dispose(bool disposing) internal override void Dispose(bool disposing)
@@ -254,10 +263,7 @@ namespace Discord.WebSocket
finally finally
{ {
if (_connectionGroupLock != null) if (_connectionGroupLock != null)
{
await Task.Delay(5000).ConfigureAwait(false);
_connectionGroupLock.Release(); _connectionGroupLock.Release();
}
} }
} }
private async Task OnDisconnectingAsync(Exception ex) private async Task OnDisconnectingAsync(Exception ex)


+ 4
- 0
src/Discord.Net.WebSocket/DiscordSocketConfig.cs View File

@@ -1,3 +1,4 @@
using Discord.Net.Queue;
using Discord.Net.Udp; using Discord.Net.Udp;
using Discord.Net.WebSockets; using Discord.Net.WebSockets;
using Discord.Rest; using Discord.Rest;
@@ -124,6 +125,8 @@ namespace Discord.WebSocket
/// </summary> /// </summary>
public bool GuildSubscriptions { get; set; } = true; public bool GuildSubscriptions { get; set; } = true;


internal RequestQueue _websocketRequestQueue;

/// <summary> /// <summary>
/// Initializes a default configuration. /// Initializes a default configuration.
/// </summary> /// </summary>
@@ -131,6 +134,7 @@ namespace Discord.WebSocket
{ {
WebSocketProvider = DefaultWebSocketProvider.Instance; WebSocketProvider = DefaultWebSocketProvider.Instance;
UdpSocketProvider = DefaultUdpSocketProvider.Instance; UdpSocketProvider = DefaultUdpSocketProvider.Instance;
_websocketRequestQueue = new RequestQueue();
} }


internal DiscordSocketConfig Clone() => MemberwiseClone() as DiscordSocketConfig; internal DiscordSocketConfig Clone() => MemberwiseClone() as DiscordSocketConfig;


Loading…
Cancel
Save