From 4d9389b3aa8a5c0930488b44078b4f637cb24cd5 Mon Sep 17 00:00:00 2001
From: Quin Lynch <49576606+quinchs@users.noreply.github.com>
Date: Fri, 14 Jan 2022 07:55:57 -0400
Subject: [PATCH] Add default ratelimit callback (#2037)
---
src/Discord.Net.Core/DiscordConfig.cs | 10 ++++++++++
src/Discord.Net.Rest/DiscordRestApiClient.cs | 12 +++++++-----
src/Discord.Net.Rest/DiscordRestClient.cs | 2 +-
src/Discord.Net.WebSocket/BaseSocketClient.cs | 4 ++--
src/Discord.Net.WebSocket/DiscordShardedClient.cs | 3 ++-
src/Discord.Net.WebSocket/DiscordSocketApiClient.cs | 4 ++--
src/Discord.Net.WebSocket/DiscordSocketClient.cs | 3 ++-
src/Discord.Net.Webhook/DiscordWebhookClient.cs | 2 +-
8 files changed, 27 insertions(+), 13 deletions(-)
diff --git a/src/Discord.Net.Core/DiscordConfig.cs b/src/Discord.Net.Core/DiscordConfig.cs
index d5951bd07..34bfc5e62 100644
--- a/src/Discord.Net.Core/DiscordConfig.cs
+++ b/src/Discord.Net.Core/DiscordConfig.cs
@@ -1,4 +1,6 @@
+using System;
using System.Reflection;
+using System.Threading.Tasks;
namespace Discord
{
@@ -131,6 +133,14 @@ namespace Discord
///
public RetryMode DefaultRetryMode { get; set; } = RetryMode.AlwaysRetry;
+ ///
+ /// Gets or sets the default callback for ratelimits.
+ ///
+ ///
+ /// This property is mutually exclusive with .
+ ///
+ public Func DefaultRatelimitCallback { get; set; }
+
///
/// Gets or sets the minimum log level severity that will be sent to the Log event.
///
diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs
index c9a4d6c30..69f150ab6 100644
--- a/src/Discord.Net.Rest/DiscordRestApiClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs
@@ -46,17 +46,19 @@ namespace Discord.API
internal IRestClient RestClient { get; private set; }
internal ulong? CurrentUserId { get; set; }
internal bool UseSystemClock { get; set; }
+ internal Func DefaultRatelimitCallback { get; set; }
internal JsonSerializer Serializer => _serializer;
/// Unknown OAuth token type.
public DiscordRestApiClient(RestClientProvider restClientProvider, string userAgent, RetryMode defaultRetryMode = RetryMode.AlwaysRetry,
- JsonSerializer serializer = null, bool useSystemClock = true)
+ JsonSerializer serializer = null, bool useSystemClock = true, Func defaultRatelimitCallback = null)
{
_restClientProvider = restClientProvider;
UserAgent = userAgent;
DefaultRetryMode = defaultRetryMode;
_serializer = serializer ?? new JsonSerializer { ContractResolver = new DiscordContractResolver() };
UseSystemClock = useSystemClock;
+ DefaultRatelimitCallback = defaultRatelimitCallback;
RequestQueue = new RequestQueue();
_stateLock = new SemaphoreSlim(1, 1);
@@ -279,10 +281,10 @@ namespace Discord.API
{
if (!request.Options.IgnoreState)
CheckState();
- if (request.Options.RetryMode == null)
- request.Options.RetryMode = DefaultRetryMode;
- if (request.Options.UseSystemClock == null)
- request.Options.UseSystemClock = UseSystemClock;
+
+ request.Options.RetryMode ??= DefaultRetryMode;
+ request.Options.UseSystemClock ??= UseSystemClock;
+ request.Options.RatelimitCallback ??= DefaultRatelimitCallback;
var stopwatch = Stopwatch.StartNew();
var responseStream = await RequestQueue.SendAsync(request).ConfigureAwait(false);
diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs
index cd2033c8c..3b4f7628d 100644
--- a/src/Discord.Net.Rest/DiscordRestClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestClient.cs
@@ -37,7 +37,7 @@ namespace Discord.Rest
internal DiscordRestClient(DiscordRestConfig config, API.DiscordRestApiClient api) : base(config, api) { }
private static API.DiscordRestApiClient CreateApiClient(DiscordRestConfig config)
- => new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent, serializer: Serializer, useSystemClock: config.UseSystemClock);
+ => new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent, serializer: Serializer, useSystemClock: config.UseSystemClock, defaultRatelimitCallback: config.DefaultRatelimitCallback);
internal override void Dispose(bool disposing)
{
diff --git a/src/Discord.Net.WebSocket/BaseSocketClient.cs b/src/Discord.Net.WebSocket/BaseSocketClient.cs
index 9e25ab382..20acd85dd 100644
--- a/src/Discord.Net.WebSocket/BaseSocketClient.cs
+++ b/src/Discord.Net.WebSocket/BaseSocketClient.cs
@@ -79,8 +79,8 @@ namespace Discord.WebSocket
internal BaseSocketClient(DiscordSocketConfig config, DiscordRestApiClient client)
: base(config, client) => BaseConfig = config;
private static DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config)
- => new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent,
- useSystemClock: config.UseSystemClock);
+ => new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayHost,
+ useSystemClock: config.UseSystemClock, defaultRatelimitCallback: config.DefaultRatelimitCallback);
///
/// Gets a Discord application information for the logged-in user.
diff --git a/src/Discord.Net.WebSocket/DiscordShardedClient.cs b/src/Discord.Net.WebSocket/DiscordShardedClient.cs
index 6e943dde3..e573a2593 100644
--- a/src/Discord.Net.WebSocket/DiscordShardedClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordShardedClient.cs
@@ -107,7 +107,8 @@ namespace Discord.WebSocket
}
}
private static API.DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config)
- => new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent);
+ => new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayHost,
+ useSystemClock: config.UseSystemClock, defaultRatelimitCallback: config.DefaultRatelimitCallback);
internal async Task AcquireIdentifyLockAsync(int shardId, CancellationToken token)
{
diff --git a/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs b/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs
index bf15967d3..cad6e5daa 100644
--- a/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs
@@ -39,8 +39,8 @@ namespace Discord.API
public DiscordSocketApiClient(RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, string userAgent,
string url = null, RetryMode defaultRetryMode = RetryMode.AlwaysRetry, JsonSerializer serializer = null,
- bool useSystemClock = true)
- : base(restClientProvider, userAgent, defaultRetryMode, serializer, useSystemClock)
+ bool useSystemClock = true, Func defaultRatelimitCallback = null)
+ : base(restClientProvider, userAgent, defaultRetryMode, serializer, useSystemClock, defaultRatelimitCallback)
{
_gatewayUrl = url;
if (url != null)
diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
index 10bf88d74..6c584f66e 100644
--- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
@@ -195,7 +195,8 @@ namespace Discord.WebSocket
_largeGuilds = new ConcurrentQueue();
}
private static API.DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config)
- => new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayHost);
+ => new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayHost,
+ useSystemClock: config.UseSystemClock, defaultRatelimitCallback: config.DefaultRatelimitCallback);
///
internal override void Dispose(bool disposing)
{
diff --git a/src/Discord.Net.Webhook/DiscordWebhookClient.cs b/src/Discord.Net.Webhook/DiscordWebhookClient.cs
index cb24f9ea1..f7bc38587 100644
--- a/src/Discord.Net.Webhook/DiscordWebhookClient.cs
+++ b/src/Discord.Net.Webhook/DiscordWebhookClient.cs
@@ -83,7 +83,7 @@ namespace Discord.Webhook
ApiClient.SentRequest += async (method, endpoint, millis) => await _restLogger.VerboseAsync($"{method} {endpoint}: {millis} ms").ConfigureAwait(false);
}
private static API.DiscordRestApiClient CreateApiClient(DiscordRestConfig config)
- => new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent);
+ => new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent, useSystemClock: config.UseSystemClock, defaultRatelimitCallback: config.DefaultRatelimitCallback);
/// Sends a message to the channel for this webhook.
/// Returns the ID of the created message.
public Task SendMessageAsync(string text = null, bool isTTS = false, IEnumerable