From 4a4b011c348ffb4234c4858b96a7e3393b575d4b Mon Sep 17 00:00:00 2001 From: Christopher F Date: Sun, 27 May 2018 20:20:49 -0400 Subject: [PATCH] feature: Add OffloadAllHandlers to config If this flag is set to true, all event handlers will be fired and forgotten. Allows owners of large bots to offload all events without needing to shove them in a Task.Run. feature request per @aStonedPenguin --- src/Discord.Net.WebSocket/DiscordSocketClient.cs | 9 ++++++++- src/Discord.Net.WebSocket/DiscordSocketConfig.cs | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index 2dccd9321..557c644e1 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -58,6 +58,7 @@ namespace Discord.WebSocket internal WebSocketProvider WebSocketProvider { get; private set; } internal bool AlwaysDownloadUsers { get; private set; } internal int? HandlerTimeout { get; private set; } + internal bool OffloadAllHandlers { get; private set; } internal new DiscordSocketApiClient ApiClient => base.ApiClient as DiscordSocketApiClient; public override IReadOnlyCollection Guilds => State.Guilds; @@ -84,9 +85,13 @@ namespace Discord.WebSocket WebSocketProvider = config.WebSocketProvider; AlwaysDownloadUsers = config.AlwaysDownloadUsers; HandlerTimeout = config.HandlerTimeout; + OffloadAllHandlers = config.OffloadAllHandlers; State = new ClientState(0, 0); _heartbeatTimes = new ConcurrentQueue(); + if (OffloadAllHandlers && !HandlerTimeout.HasValue) + throw new InvalidOperationException("If OffloadAllHandlers is set, the HandlerTimeout must also be set. To suppress this message, unset OffloadAllHandlers"); + _stateLock = new SemaphoreSlim(1, 1); _gatewayLogger = LogManager.CreateLogger(ShardId == 0 && TotalShards == 1 ? "Gateway" : $"Shard #{ShardId}"); _connection = new ConnectionManager(_stateLock, _gatewayLogger, config.ConnectionTimeout, @@ -1733,8 +1738,10 @@ namespace Discord.WebSocket { try { - var timeoutTask = Task.Delay(HandlerTimeout.Value); var handlersTask = action(); + if (OffloadAllHandlers) + return; + var timeoutTask = Task.Delay(HandlerTimeout.Value); if (await Task.WhenAny(timeoutTask, handlersTask).ConfigureAwait(false) == timeoutTask) { await _gatewayLogger.WarningAsync($"A {name} handler is blocking the gateway task.").ConfigureAwait(false); diff --git a/src/Discord.Net.WebSocket/DiscordSocketConfig.cs b/src/Discord.Net.WebSocket/DiscordSocketConfig.cs index 3f9c18863..72aa93c24 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketConfig.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketConfig.cs @@ -1,4 +1,4 @@ -using Discord.Net.Udp; +using Discord.Net.Udp; using Discord.Net.WebSockets; using Discord.Rest; @@ -35,6 +35,8 @@ namespace Discord.WebSocket public bool AlwaysDownloadUsers { get; set; } = false; /// Gets or sets the timeout for event handlers, in milliseconds, after which a warning will be logged. Null disables this check. public int? HandlerTimeout { get; set; } = 3000; + /// Gets or sets whether or not offload all event handlers from the gateway task. This can have dangerous consequences. + public bool OffloadAllHandlers { get; set; } = false; public DiscordSocketConfig() {