Use a memory cache with expiration

This commit is contained in:
Ryan Whytsell 2025-07-18 19:32:39 -04:00
parent 795978c1e8
commit acee597910
Signed by: Epithium
GPG Key ID: 940AC18C08E925EA
2 changed files with 10 additions and 6 deletions

View File

@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using Microsoft.Extensions.Caching.Memory;
using NetCord;
using NetCord.Gateway;
using NetCord.Hosting.Gateway;
@ -34,6 +35,7 @@ public class Program
});
builder.Services.AddSingleton<VoiceStateManager>();
builder.Services.AddSingleton<VoiceStatesHandler>();
builder.Services.AddSingleton<IMemoryCache>(new MemoryCache(new MemoryCacheOptions()));
builder.Services.AddDiscordGateway(options =>
{
options.Intents = GatewayIntents.GuildMessages

View File

@ -1,3 +1,4 @@
using Microsoft.Extensions.Caching.Memory;
using NetCord;
using NetCord.Gateway;
using NetCord.Hosting.Gateway;
@ -11,14 +12,14 @@ public class VoiceStateManager
// Key: GuildId Value: List of UserId for users in voice channel
// TODO: We probably want to persist this somewhere else (Redis/Valkey)
private Dictionary<ulong, ISet<ulong>> _guildVoiceStates;
private Dictionary<ulong, DateTimeOffset> _yapperNotificationTimeouts;
private IMemoryCache _yapperNotificationTimeoutCache;
private RestClient _restClient;
private ILogger<VoiceStateManager> _logger;
public VoiceStateManager(ILogger<VoiceStateManager> logger, RestClient restClient)
public VoiceStateManager(ILogger<VoiceStateManager> logger, RestClient restClient, IMemoryCache yapperNotificationTimeoutCache)
{
_guildVoiceStates = new Dictionary<ulong, ISet<ulong>>();
_yapperNotificationTimeouts = new Dictionary<ulong, DateTimeOffset>();
_yapperNotificationTimeoutCache = yapperNotificationTimeoutCache;
_restClient = restClient ?? throw new System.ArgumentNullException(nameof(restClient));
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
}
@ -36,11 +37,11 @@ public class VoiceStateManager
var guildRoles = await _restClient.GetGuildRolesAsync(voice_state.GuildId,
new RestRequestProperties() { AuditLogReason = "Role lookup" });
var yapperRoleId = guildRoles.FirstOrDefault(role => role.Name.ToLower() == "yapper")?.Id;
if (alertChannelId is not null && yapperRoleId is not null && (!_yapperNotificationTimeouts.TryGetValue(voice_state.GuildId, out var timeout) || DateTimeOffset.UtcNow.CompareTo(timeout) > 0))
if (alertChannelId is not null && yapperRoleId is not null && (!_yapperNotificationTimeoutCache.TryGetValue(voice_state.GuildId, out DateTimeOffset timeout) || DateTimeOffset.UtcNow.CompareTo(timeout) > 0))
{
// Notify that new yapper has arrived
await _restClient.SendMessageAsync(
alertChannelId.GetValueOrDefault(),
alertChannelId.GetValueOrDefault(),
new MessageProperties()
{
AllowedMentions = new AllowedMentionsProperties() {AllowedRoles = [yapperRoleId.GetValueOrDefault()]},
@ -64,7 +65,8 @@ public class VoiceStateManager
{
yappers.Remove(voice_state.UserId);
_guildVoiceStates[voice_state.GuildId] = yappers;
_yapperNotificationTimeouts[voice_state.GuildId] = DateTimeOffset.UtcNow.AddHours(2);
var expiration = DateTimeOffset.UtcNow.AddHours(2);
_yapperNotificationTimeoutCache.Set(voice_state.GuildId, expiration, expiration);
}
}