From 12aef1f61d7a43d7902eb33681a3c82db4c98199 Mon Sep 17 00:00:00 2001 From: Ske Date: Wed, 29 Apr 2020 01:14:49 +0200 Subject: [PATCH] Refactor periodic event loop --- PluralKit.Bot/Bot.cs | 59 +++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/PluralKit.Bot/Bot.cs b/PluralKit.Bot/Bot.cs index f4e20706..4e49b8ac 100644 --- a/PluralKit.Bot/Bot.cs +++ b/PluralKit.Bot/Bot.cs @@ -15,6 +15,8 @@ using DSharpPlus.EventArgs; using Microsoft.Extensions.Configuration; +using NodaTime; + using PluralKit.Core; using Sentry; @@ -106,7 +108,8 @@ namespace PluralKit.Bot private ILogger _logger; private WebhookRateLimitService _webhookRateLimit; private int _periodicUpdateCount; - + private Task _periodicWorker; + public Bot(ILifetimeScope services, DiscordShardedClient client, IMetrics metrics, PeriodicStatCollector collector, ILogger logger, WebhookRateLimitService webhookRateLimit) { _services = services; @@ -131,6 +134,9 @@ namespace PluralKit.Bot _client.MessageUpdated += args => HandleEvent(eh => eh.HandleMessageEdited(args)); _services.Resolve().Init(_client); + + // Will not be awaited, just runs in the background + _periodicWorker = UpdatePeriodic(); return Task.CompletedTask; } @@ -158,43 +164,40 @@ namespace PluralKit.Bot _logger.Write(level, args.Exception, "D#+ {Source}: {Message}", args.Application, args.Message); } - - // Method called every 60 seconds + private async Task UpdatePeriodic() { - // Change bot status - var totalGuilds = _client.ShardClients.Values.Sum(c => c.Guilds.Count); - try // DiscordClient may throw an exception if the socket is closed (e.g just after OP 7 received) + while (true) { - await _client.UpdateStatusAsync(new DiscordActivity($"pk;help | in {totalGuilds} servers")); - } - catch (WebSocketException) { } + // Run at every whole minute (:00), mostly because I feel like it + var timeNow = SystemClock.Instance.GetCurrentInstant(); + var timeTillNextWholeMinute = 60000 - (timeNow.ToUnixTimeMilliseconds() % 60000); + await Task.Delay((int) timeTillNextWholeMinute); + + // Change bot status + var totalGuilds = _client.ShardClients.Values.Sum(c => c.Guilds.Count); + try // DiscordClient may throw an exception if the socket is closed (e.g just after OP 7 received) + { + await _client.UpdateStatusAsync(new DiscordActivity($"pk;help | in {totalGuilds} servers")); + } + catch (WebSocketException) { } - // Run webhook rate limit GC every 10 minutes - if (_periodicUpdateCount++ % 10 == 0) - { - var _ = Task.Run(() => _webhookRateLimit.GarbageCollect()); - } + // Run webhook rate limit GC every 10 minutes + if (_periodicUpdateCount++ % 10 == 0) + { + var _ = Task.Run(() => _webhookRateLimit.GarbageCollect()); + } - await _collector.CollectStats(); - - _logger.Information("Submitted metrics to backend"); - await Task.WhenAll(((IMetricsRoot) _metrics).ReportRunner.RunAllAsync()); + await _collector.CollectStats(); + + _logger.Information("Submitted metrics to backend"); + await Task.WhenAll(((IMetricsRoot) _metrics).ReportRunner.RunAllAsync()); + } } private Task ShardReady(ReadyEventArgs e) { _logger.Information("Shard {Shard} connected to {ChannelCount} channels in {GuildCount} guilds", e.Client.ShardId, e.Client.Guilds.Sum(g => g.Value.Channels.Count), e.Client.Guilds.Count); - - if (e.Client.ShardId == 0) - { - _updateTimer = new Timer((_) => { - HandleEvent(_ => UpdatePeriodic()); - }, null, TimeSpan.Zero, TimeSpan.FromMinutes(1)); - - _logger.Information("PluralKit started as {Username}#{Discriminator} ({Id})", _client.CurrentUser.Username, _client.CurrentUser.Discriminator, _client.CurrentUser.Id); - } - return Task.CompletedTask; }