feat(api): also clear cache when leaving a guild

This commit is contained in:
sam 2024-10-24 21:10:54 +02:00
parent 5c57b75335
commit 439051999f
Signed by: sam
GPG key ID: 5F3C3C1B3166639D
10 changed files with 53 additions and 0 deletions

View file

@ -101,6 +101,14 @@ public partial class GuildsController
guildId 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); _logger.Information("Left guild {GuildId} and removed all data for it", guildId);
return NoContent(); return NoContent();

View file

@ -33,8 +33,12 @@ namespace Catalogger.Backend.Api;
public partial class GuildsController( public partial class GuildsController(
ILogger logger, ILogger logger,
DatabaseContext db, DatabaseContext db,
GuildCache guildCache,
EmojiCache emojiCache,
ChannelCache channelCache, ChannelCache channelCache,
RoleCache roleCache,
IMemberCache memberCache, IMemberCache memberCache,
IInviteCache inviteCache,
DiscordRequestService discordRequestService, DiscordRequestService discordRequestService,
IDiscordRestUserAPI userApi, IDiscordRestUserAPI userApi,
WebhookExecutorService webhookExecutor WebhookExecutorService webhookExecutor

View file

@ -22,4 +22,5 @@ public interface IInviteCache
{ {
public Task<IEnumerable<IInviteWithMetadata>> TryGetAsync(Snowflake guildId); public Task<IEnumerable<IInviteWithMetadata>> TryGetAsync(Snowflake guildId);
public Task SetAsync(Snowflake guildId, IEnumerable<IInviteWithMetadata> invites); public Task SetAsync(Snowflake guildId, IEnumerable<IInviteWithMetadata> invites);
public Task RemoveAsync(Snowflake guildId);
} }

View file

@ -46,4 +46,6 @@ public interface IMemberCache
); );
public Task TryRemoveMemberNameAsync(Snowflake guildId, string username); public Task TryRemoveMemberNameAsync(Snowflake guildId, string username);
public Task RemoveAllMembersAsync(Snowflake guildId);
} }

View file

@ -81,4 +81,17 @@ public class ChannelCache
.Select(id => _channels.GetValueOrDefault(id)) .Select(id => _channels.GetValueOrDefault(id))
.Where(c => c != null) .Where(c => c != null)
.Select(c => c!); .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 _);
}
} }

View file

@ -30,4 +30,6 @@ public class EmojiCache
_emojis.TryGetValue(guildId, out emoji); _emojis.TryGetValue(guildId, out emoji);
public int Size => _emojis.Select(kv => kv.Value.Count).Sum(); public int Size => _emojis.Select(kv => kv.Value.Count).Sum();
public bool Remove(Snowflake guildId) => _emojis.Remove(guildId, out _);
} }

View file

@ -34,4 +34,10 @@ public class InMemoryInviteCache : IInviteCache
_invites[guildId] = invites; _invites[guildId] = invites;
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task RemoveAsync(Snowflake guildId)
{
_invites.Remove(guildId, out _);
return Task.CompletedTask;
}
} }

View file

@ -145,4 +145,13 @@ public class InMemoryMemberCache(IDiscordRestGuildAPI guildApi, ILogger logger)
) => Task.FromResult<IEnumerable<(string, string)>>([]); ) => Task.FromResult<IEnumerable<(string, string)>>([]);
public Task TryRemoveMemberNameAsync(Snowflake guildId, string username) => Task.CompletedTask; 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;
}
} }

View file

@ -33,6 +33,9 @@ public class RedisInviteCache(RedisService redisService) : IInviteCache
public async Task SetAsync(Snowflake guildId, IEnumerable<IInviteWithMetadata> invites) => public async Task SetAsync(Snowflake guildId, IEnumerable<IInviteWithMetadata> invites) =>
await redisService.SetAsync(InvitesKey(guildId), invites.Select(RedisInvite.FromIInvite)); 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}"; private static string InvitesKey(Snowflake guildId) => $"guild-invites:{guildId}";
} }

View file

@ -192,6 +192,11 @@ public class RedisMemberCache(
public async Task TryRemoveMemberNameAsync(Snowflake guildId, string username) => public async Task TryRemoveMemberNameAsync(Snowflake guildId, string username) =>
await redisService.GetDatabase().HashDeleteAsync(MemberNamesKey(guildId), 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 const string GuildCacheKey = "cached-guilds";
private static string GuildMembersKey(Snowflake guildId) => $"guild-members:{guildId}"; private static string GuildMembersKey(Snowflake guildId) => $"guild-members:{guildId}";