feat: globally rate-limit sending errors, rather than per-channel

This commit is contained in:
spiral 2021-11-09 01:48:47 -05:00
parent e5c74edd85
commit ec3795f9d0
No known key found for this signature in database
GPG Key ID: A6059F0CA0E1BD31

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Diagnostics;
using System.Threading.Tasks; using System.Threading.Tasks;
using App.Metrics; using App.Metrics;
@ -15,8 +16,12 @@ namespace PluralKit.Bot
{ {
public class ErrorMessageService public class ErrorMessageService
{ {
// globally rate limit errors for now, don't want to spam users when something breaks
private static readonly Duration MinErrorInterval = Duration.FromSeconds(10); private static readonly Duration MinErrorInterval = Duration.FromSeconds(10);
private readonly ConcurrentDictionary<ulong, Instant> _lastErrorInChannel = new ConcurrentDictionary<ulong, Instant>(); private static readonly Duration IntervalFromStartup = Duration.FromMinutes(5);
// private readonly ConcurrentDictionary<ulong, Instant> _lastErrorInChannel = new ConcurrentDictionary<ulong, Instant>();
private Instant lastErrorTime { get; set; }
private readonly IMetrics _metrics; private readonly IMetrics _metrics;
private readonly ILogger _logger; private readonly ILogger _logger;
@ -27,6 +32,8 @@ namespace PluralKit.Bot
_metrics = metrics; _metrics = metrics;
_logger = logger; _logger = logger;
_rest = rest; _rest = rest;
lastErrorTime = SystemClock.Instance.GetCurrentInstant();
} }
public async Task SendErrorMessage(ulong channelId, string errorId) public async Task SendErrorMessage(ulong channelId, string errorId)
@ -67,14 +74,20 @@ namespace PluralKit.Bot
private bool ShouldSendErrorMessage(ulong channelId, Instant now) private bool ShouldSendErrorMessage(ulong channelId, Instant now)
{ {
if (_lastErrorInChannel.TryGetValue(channelId, out var lastErrorTime)) // if (_lastErrorInChannel.TryGetValue(channelId, out var lastErrorTime))
{
var interval = now - lastErrorTime;
if (interval < MinErrorInterval)
return false;
}
_lastErrorInChannel[channelId] = now; var startupTime = Instant.FromDateTimeUtc(Process.GetCurrentProcess().StartTime);
// don't send errors during startup
// mostly because Npgsql throws a bunch of errors when opening connections sometimes???
if ((now - startupTime) < IntervalFromStartup)
return false;
var interval = now - lastErrorTime;
if (interval < MinErrorInterval)
return false;
// _lastErrorInChannel[channelId] = now;
lastErrorTime = now;
return true; return true;
} }
} }