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

View File

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