From 439051999fada108c98b5e74ad4d444a8384b57b Mon Sep 17 00:00:00 2001 From: sam Date: Thu, 24 Oct 2024 21:10:54 +0200 Subject: [PATCH] feat(api): also clear cache when leaving a guild --- Catalogger.Backend/Api/GuildsController.Remove.cs | 8 ++++++++ Catalogger.Backend/Api/GuildsController.cs | 4 ++++ Catalogger.Backend/Cache/IInviteCache.cs | 1 + Catalogger.Backend/Cache/IMemberCache.cs | 2 ++ .../Cache/InMemoryCache/ChannelCache.cs | 13 +++++++++++++ .../Cache/InMemoryCache/EmojiCache.cs | 2 ++ .../Cache/InMemoryCache/InMemoryInviteCache.cs | 6 ++++++ .../Cache/InMemoryCache/InMemoryMemberCache.cs | 9 +++++++++ .../Cache/RedisCache/RedisInviteCache.cs | 3 +++ .../Cache/RedisCache/RedisMemberCache.cs | 5 +++++ 10 files changed, 53 insertions(+) diff --git a/Catalogger.Backend/Api/GuildsController.Remove.cs b/Catalogger.Backend/Api/GuildsController.Remove.cs index 5f4d2f6..d7fdc7d 100644 --- a/Catalogger.Backend/Api/GuildsController.Remove.cs +++ b/Catalogger.Backend/Api/GuildsController.Remove.cs @@ -101,6 +101,14 @@ public partial class GuildsController guildId ); + // Clear out the caches for this guild + guildCache.Remove(guildId, out _); + emojiCache.Remove(guildId); + channelCache.RemoveGuild(guildId); + roleCache.RemoveGuild(guildId); + await memberCache.RemoveAllMembersAsync(guildId); + await inviteCache.RemoveAsync(guildId); + _logger.Information("Left guild {GuildId} and removed all data for it", guildId); return NoContent(); diff --git a/Catalogger.Backend/Api/GuildsController.cs b/Catalogger.Backend/Api/GuildsController.cs index f7210a7..4d2bba4 100644 --- a/Catalogger.Backend/Api/GuildsController.cs +++ b/Catalogger.Backend/Api/GuildsController.cs @@ -33,8 +33,12 @@ namespace Catalogger.Backend.Api; public partial class GuildsController( ILogger logger, DatabaseContext db, + GuildCache guildCache, + EmojiCache emojiCache, ChannelCache channelCache, + RoleCache roleCache, IMemberCache memberCache, + IInviteCache inviteCache, DiscordRequestService discordRequestService, IDiscordRestUserAPI userApi, WebhookExecutorService webhookExecutor diff --git a/Catalogger.Backend/Cache/IInviteCache.cs b/Catalogger.Backend/Cache/IInviteCache.cs index bb6be26..bc3c902 100644 --- a/Catalogger.Backend/Cache/IInviteCache.cs +++ b/Catalogger.Backend/Cache/IInviteCache.cs @@ -22,4 +22,5 @@ public interface IInviteCache { public Task> TryGetAsync(Snowflake guildId); public Task SetAsync(Snowflake guildId, IEnumerable invites); + public Task RemoveAsync(Snowflake guildId); } diff --git a/Catalogger.Backend/Cache/IMemberCache.cs b/Catalogger.Backend/Cache/IMemberCache.cs index 1c108a3..857ab2f 100644 --- a/Catalogger.Backend/Cache/IMemberCache.cs +++ b/Catalogger.Backend/Cache/IMemberCache.cs @@ -46,4 +46,6 @@ public interface IMemberCache ); public Task TryRemoveMemberNameAsync(Snowflake guildId, string username); + + public Task RemoveAllMembersAsync(Snowflake guildId); } diff --git a/Catalogger.Backend/Cache/InMemoryCache/ChannelCache.cs b/Catalogger.Backend/Cache/InMemoryCache/ChannelCache.cs index bc6bc50..1e00ed4 100644 --- a/Catalogger.Backend/Cache/InMemoryCache/ChannelCache.cs +++ b/Catalogger.Backend/Cache/InMemoryCache/ChannelCache.cs @@ -81,4 +81,17 @@ public class ChannelCache .Select(id => _channels.GetValueOrDefault(id)) .Where(c => c != null) .Select(c => c!); + + public void RemoveGuild(Snowflake guildId) + { + if (!_guildChannels.TryGetValue(guildId, out var channelIds)) + return; + + foreach (var id in channelIds) + { + _channels.Remove(id, out _); + } + + _guildChannels.Remove(guildId, out _); + } } diff --git a/Catalogger.Backend/Cache/InMemoryCache/EmojiCache.cs b/Catalogger.Backend/Cache/InMemoryCache/EmojiCache.cs index 734661c..399dac7 100644 --- a/Catalogger.Backend/Cache/InMemoryCache/EmojiCache.cs +++ b/Catalogger.Backend/Cache/InMemoryCache/EmojiCache.cs @@ -30,4 +30,6 @@ public class EmojiCache _emojis.TryGetValue(guildId, out emoji); public int Size => _emojis.Select(kv => kv.Value.Count).Sum(); + + public bool Remove(Snowflake guildId) => _emojis.Remove(guildId, out _); } diff --git a/Catalogger.Backend/Cache/InMemoryCache/InMemoryInviteCache.cs b/Catalogger.Backend/Cache/InMemoryCache/InMemoryInviteCache.cs index 6ab4c12..83f0b66 100644 --- a/Catalogger.Backend/Cache/InMemoryCache/InMemoryInviteCache.cs +++ b/Catalogger.Backend/Cache/InMemoryCache/InMemoryInviteCache.cs @@ -34,4 +34,10 @@ public class InMemoryInviteCache : IInviteCache _invites[guildId] = invites; return Task.CompletedTask; } + + public Task RemoveAsync(Snowflake guildId) + { + _invites.Remove(guildId, out _); + return Task.CompletedTask; + } } diff --git a/Catalogger.Backend/Cache/InMemoryCache/InMemoryMemberCache.cs b/Catalogger.Backend/Cache/InMemoryCache/InMemoryMemberCache.cs index 45a271c..8452028 100644 --- a/Catalogger.Backend/Cache/InMemoryCache/InMemoryMemberCache.cs +++ b/Catalogger.Backend/Cache/InMemoryCache/InMemoryMemberCache.cs @@ -145,4 +145,13 @@ public class InMemoryMemberCache(IDiscordRestGuildAPI guildApi, ILogger logger) ) => Task.FromResult>([]); public Task TryRemoveMemberNameAsync(Snowflake guildId, string username) => Task.CompletedTask; + + public Task RemoveAllMembersAsync(Snowflake guildId) + { + foreach (var kv in _members.Where(kv => kv.Key.GuildId == guildId)) + _members.Remove(kv.Key, out _); + + _guilds.Remove(guildId, out _); + return Task.CompletedTask; + } } diff --git a/Catalogger.Backend/Cache/RedisCache/RedisInviteCache.cs b/Catalogger.Backend/Cache/RedisCache/RedisInviteCache.cs index 10f3a38..e85d1f2 100644 --- a/Catalogger.Backend/Cache/RedisCache/RedisInviteCache.cs +++ b/Catalogger.Backend/Cache/RedisCache/RedisInviteCache.cs @@ -33,6 +33,9 @@ public class RedisInviteCache(RedisService redisService) : IInviteCache public async Task SetAsync(Snowflake guildId, IEnumerable invites) => await redisService.SetAsync(InvitesKey(guildId), invites.Select(RedisInvite.FromIInvite)); + public async Task RemoveAsync(Snowflake guildId) => + await redisService.GetDatabase().KeyDeleteAsync(InvitesKey(guildId)); + private static string InvitesKey(Snowflake guildId) => $"guild-invites:{guildId}"; } diff --git a/Catalogger.Backend/Cache/RedisCache/RedisMemberCache.cs b/Catalogger.Backend/Cache/RedisCache/RedisMemberCache.cs index 302f80e..dfa9694 100644 --- a/Catalogger.Backend/Cache/RedisCache/RedisMemberCache.cs +++ b/Catalogger.Backend/Cache/RedisCache/RedisMemberCache.cs @@ -192,6 +192,11 @@ public class RedisMemberCache( public async Task TryRemoveMemberNameAsync(Snowflake guildId, string username) => await redisService.GetDatabase().HashDeleteAsync(MemberNamesKey(guildId), username); + public async Task RemoveAllMembersAsync(Snowflake guildId) => + await redisService + .GetDatabase() + .KeyDeleteAsync([GuildMembersKey(guildId), MemberNamesKey(guildId)]); + private const string GuildCacheKey = "cached-guilds"; private static string GuildMembersKey(Snowflake guildId) => $"guild-members:{guildId}";