diff --git a/Catalogger.Backend/Api/GuildsController.Remove.cs b/Catalogger.Backend/Api/GuildsController.Remove.cs index d7fdc7d..1490884 100644 --- a/Catalogger.Backend/Api/GuildsController.Remove.cs +++ b/Catalogger.Backend/Api/GuildsController.Remove.cs @@ -40,7 +40,7 @@ public partial class GuildsController ); } - var guildConfig = await db.GetGuildAsync(guildId.Value); + var guildConfig = await db.GetGuildAsync(guildId.Value, false); var logChannelId = webhookExecutor.GetLogChannel(guildConfig, LogChannelType.GuildUpdate) ?? webhookExecutor.GetLogChannel(guildConfig, LogChannelType.GuildMemberRemove); diff --git a/Catalogger.Backend/Api/GuildsController.cs b/Catalogger.Backend/Api/GuildsController.cs index 4d2bba4..b21176b 100644 --- a/Catalogger.Backend/Api/GuildsController.cs +++ b/Catalogger.Backend/Api/GuildsController.cs @@ -70,7 +70,7 @@ public partial class GuildsController( { var (guildId, guild) = await ParseGuildAsync(id); - var guildConfig = await db.GetGuildAsync(guildId.Value); + var guildConfig = await db.GetGuildAsync(guildId.Value, false); var channels = channelCache .GuildChannels(guildId) diff --git a/Catalogger.Backend/Bot/Commands/MetaCommands.cs b/Catalogger.Backend/Bot/Commands/MetaCommands.cs index 191830b..8f516f1 100644 --- a/Catalogger.Backend/Bot/Commands/MetaCommands.cs +++ b/Catalogger.Backend/Bot/Commands/MetaCommands.cs @@ -227,7 +227,7 @@ public class MetaCommands( try { - var query = HttpUtility.UrlEncode("delta(catalogger_received_messages[5m])"); + var query = HttpUtility.UrlEncode("increase(catalogger_received_messages[5m])"); var resp = await _client.GetAsync($"http://localhost:9090/api/v1/query?query={query}"); resp.EnsureSuccessStatusCode(); diff --git a/Catalogger.Backend/Bot/Responders/Channels/ChannelCreateResponder.cs b/Catalogger.Backend/Bot/Responders/Channels/ChannelCreateResponder.cs index c192237..f1c4b8f 100644 --- a/Catalogger.Backend/Bot/Responders/Channels/ChannelCreateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Channels/ChannelCreateResponder.cs @@ -96,7 +96,7 @@ public class ChannelCreateResponder( } } - var guildConfig = await db.GetGuildAsync(ch.GuildID.Value, ct); + var guildConfig = await db.GetGuildAsync(ch.GuildID.Value, false, ct); webhookExecutor.QueueLog( guildConfig, LogChannelType.ChannelCreate, diff --git a/Catalogger.Backend/Bot/Responders/Channels/ChannelDeleteResponder.cs b/Catalogger.Backend/Bot/Responders/Channels/ChannelDeleteResponder.cs index 5d10024..a10eed7 100644 --- a/Catalogger.Backend/Bot/Responders/Channels/ChannelDeleteResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Channels/ChannelDeleteResponder.cs @@ -49,7 +49,7 @@ public class ChannelDeleteResponder( return Result.Success; } - var guildConfig = await db.GetGuildAsync(evt.GuildID.Value, ct); + var guildConfig = await db.GetGuildAsync(evt.GuildID.Value, false, ct); var embed = new EmbedBuilder() .WithTitle("Channel deleted") .WithColour(DiscordUtils.Red) diff --git a/Catalogger.Backend/Bot/Responders/Channels/ChannelUpdateResponder.cs b/Catalogger.Backend/Bot/Responders/Channels/ChannelUpdateResponder.cs index 64848a8..591cbe1 100644 --- a/Catalogger.Backend/Bot/Responders/Channels/ChannelUpdateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Channels/ChannelUpdateResponder.cs @@ -49,7 +49,7 @@ public class ChannelUpdateResponder( return Result.Success; } - var guildConfig = await db.GetGuildAsync(evt.GuildID.Value, ct); + var guildConfig = await db.GetGuildAsync(evt.GuildID.Value, false, ct); var builder = new EmbedBuilder() .WithTitle( diff --git a/Catalogger.Backend/Bot/Responders/Guilds/GuildBanAddResponder.cs b/Catalogger.Backend/Bot/Responders/Guilds/GuildBanAddResponder.cs index 67fa8ea..80e0196 100644 --- a/Catalogger.Backend/Bot/Responders/Guilds/GuildBanAddResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Guilds/GuildBanAddResponder.cs @@ -38,7 +38,7 @@ public class GuildBanAddResponder( public async Task RespondAsync(IGuildBanAdd evt, CancellationToken ct = default) { - var guildConfig = await db.GetGuildAsync(evt.GuildID, ct); + var guildConfig = await db.GetGuildAsync(evt.GuildID, true, ct); // Delay 2 seconds for the audit log await Task.Delay(2000, ct); diff --git a/Catalogger.Backend/Bot/Responders/Guilds/GuildBanRemoveResponder.cs b/Catalogger.Backend/Bot/Responders/Guilds/GuildBanRemoveResponder.cs index a20c631..35d7363 100644 --- a/Catalogger.Backend/Bot/Responders/Guilds/GuildBanRemoveResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Guilds/GuildBanRemoveResponder.cs @@ -38,7 +38,7 @@ public class GuildBanRemoveResponder( public async Task RespondAsync(IGuildBanRemove evt, CancellationToken ct = default) { - var guildConfig = await db.GetGuildAsync(evt.GuildID, ct); + var guildConfig = await db.GetGuildAsync(evt.GuildID, false, ct); // Delay 2 seconds for the audit log await Task.Delay(2000, ct); diff --git a/Catalogger.Backend/Bot/Responders/Guilds/GuildEmojisUpdateResponder.cs b/Catalogger.Backend/Bot/Responders/Guilds/GuildEmojisUpdateResponder.cs index b7e2c7e..48d26f7 100644 --- a/Catalogger.Backend/Bot/Responders/Guilds/GuildEmojisUpdateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Guilds/GuildEmojisUpdateResponder.cs @@ -111,7 +111,7 @@ public class GuildEmojisUpdateResponder( return Result.Success; } - var guildConfig = await db.GetGuildAsync(evt.GuildID, ct); + var guildConfig = await db.GetGuildAsync(evt.GuildID, false, ct); webhookExecutor.QueueLog(guildConfig, LogChannelType.GuildEmojisUpdate, embed); return Result.Success; } diff --git a/Catalogger.Backend/Bot/Responders/Guilds/GuildUpdateResponder.cs b/Catalogger.Backend/Bot/Responders/Guilds/GuildUpdateResponder.cs index 4ee63f6..23f3458 100644 --- a/Catalogger.Backend/Bot/Responders/Guilds/GuildUpdateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Guilds/GuildUpdateResponder.cs @@ -97,7 +97,7 @@ public class GuildUpdateResponder( if (embed.Fields.Count != 0) { - var guildConfig = await db.GetGuildAsync(evt.ID, ct); + var guildConfig = await db.GetGuildAsync(evt.ID, false, ct); webhookExecutor.QueueLog( guildConfig, LogChannelType.GuildUpdate, diff --git a/Catalogger.Backend/Bot/Responders/Invites/InviteCreateResponder.cs b/Catalogger.Backend/Bot/Responders/Invites/InviteCreateResponder.cs index 39ee5c5..11a7444 100644 --- a/Catalogger.Backend/Bot/Responders/Invites/InviteCreateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Invites/InviteCreateResponder.cs @@ -74,7 +74,7 @@ public class InviteCreateResponder( inline: true ); - var guildConfig = await db.GetGuildAsync(guildId, ct); + var guildConfig = await db.GetGuildAsync(guildId, false, ct); webhookExecutor.QueueLog( guildConfig, LogChannelType.InviteCreate, diff --git a/Catalogger.Backend/Bot/Responders/Invites/InviteDeleteResponder.cs b/Catalogger.Backend/Bot/Responders/Invites/InviteDeleteResponder.cs index cdb4612..e5a5351 100644 --- a/Catalogger.Backend/Bot/Responders/Invites/InviteDeleteResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Invites/InviteDeleteResponder.cs @@ -89,7 +89,7 @@ public class InviteDeleteResponder( inline: true ); - var guildConfig = await db.GetGuildAsync(guildId, ct); + var guildConfig = await db.GetGuildAsync(guildId, false, ct); webhookExecutor.QueueLog( guildConfig, LogChannelType.InviteDelete, diff --git a/Catalogger.Backend/Bot/Responders/Members/GuildMemberAddResponder.cs b/Catalogger.Backend/Bot/Responders/Members/GuildMemberAddResponder.cs index d2a4af0..abbbd8b 100644 --- a/Catalogger.Backend/Bot/Responders/Members/GuildMemberAddResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Members/GuildMemberAddResponder.cs @@ -62,7 +62,7 @@ public class GuildMemberAddResponder( .WithCurrentTimestamp() .WithFooter($"ID: {user.ID}"); - var guildConfig = await db.GetGuildAsync(member.GuildID, ct); + var guildConfig = await db.GetGuildAsync(member.GuildID, false, ct); var guildRes = await guildApi.GetGuildAsync(member.GuildID, withCounts: true, ct); if (guildRes.IsSuccess && guildRes.Entity.ApproximateMemberCount.IsDefined()) builder.Description += diff --git a/Catalogger.Backend/Bot/Responders/Members/GuildMemberRemoveResponder.cs b/Catalogger.Backend/Bot/Responders/Members/GuildMemberRemoveResponder.cs index 9734556..0e95276 100644 --- a/Catalogger.Backend/Bot/Responders/Members/GuildMemberRemoveResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Members/GuildMemberRemoveResponder.cs @@ -50,7 +50,7 @@ public class GuildMemberRemoveResponder( .WithFooter($"ID: {evt.User.ID}") .WithCurrentTimestamp(); - var guildConfig = await db.GetGuildAsync(evt.GuildID, ct); + var guildConfig = await db.GetGuildAsync(evt.GuildID, false, ct); var member = await memberCache.TryGetAsync(evt.GuildID, evt.User.ID); if (member == null) diff --git a/Catalogger.Backend/Bot/Responders/Members/GuildMemberUpdateResponder.cs b/Catalogger.Backend/Bot/Responders/Members/GuildMemberUpdateResponder.cs index 6052a5f..96a5a92 100644 --- a/Catalogger.Backend/Bot/Responders/Members/GuildMemberUpdateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Members/GuildMemberUpdateResponder.cs @@ -145,7 +145,7 @@ public class GuildMemberUpdateResponder( .GetOrThrow(); } - var guildConfig = await db.GetGuildAsync(newMember.GuildID, ct); + var guildConfig = await db.GetGuildAsync(newMember.GuildID, false, ct); webhookExecutor.QueueLog(guildConfig, LogChannelType.GuildMemberAvatarUpdate, embed); return Result.Success; } @@ -204,7 +204,7 @@ public class GuildMemberUpdateResponder( ); } - var guildConfig = await db.GetGuildAsync(newMember.GuildID, ct); + var guildConfig = await db.GetGuildAsync(newMember.GuildID, false, ct); webhookExecutor.QueueLog( guildConfig, LogChannelType.GuildMemberNickUpdate, @@ -253,7 +253,7 @@ public class GuildMemberUpdateResponder( embed.AddField("Reason", "*(unknown)*"); } - var guildConfig = await db.GetGuildAsync(member.GuildID, ct); + var guildConfig = await db.GetGuildAsync(member.GuildID, false, ct); webhookExecutor.QueueLog( guildConfig, LogChannelType.GuildMemberTimeout, @@ -268,7 +268,7 @@ public class GuildMemberUpdateResponder( CancellationToken ct = default ) { - var guildConfig = await db.GetGuildAsync(member.GuildID, ct); + var guildConfig = await db.GetGuildAsync(member.GuildID, false, ct); var guildRoles = roleCache.GuildRoles(member.GuildID).ToList(); var keyRoleUpdate = new EmbedBuilder() diff --git a/Catalogger.Backend/Bot/Responders/Messages/MessageCreateResponder.cs b/Catalogger.Backend/Bot/Responders/Messages/MessageCreateResponder.cs index 8363aa9..2fe0789 100644 --- a/Catalogger.Backend/Bot/Responders/Messages/MessageCreateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Messages/MessageCreateResponder.cs @@ -52,7 +52,7 @@ public class MessageCreateResponder( return Result.Success; } - var guild = await db.GetGuildAsync(msg.GuildID, ct); + var guild = await db.GetGuildAsync(msg.GuildID, false, ct); // The guild needs to have enabled at least one of the message logging events, // and the channel must not be ignored, to store the message. if (guild.IsMessageIgnored(msg.ChannelID, msg.Author.ID)) diff --git a/Catalogger.Backend/Bot/Responders/Messages/MessageDeleteBulkResponder.cs b/Catalogger.Backend/Bot/Responders/Messages/MessageDeleteBulkResponder.cs index dda80f5..903fdba 100644 --- a/Catalogger.Backend/Bot/Responders/Messages/MessageDeleteBulkResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Messages/MessageDeleteBulkResponder.cs @@ -42,7 +42,7 @@ public class MessageDeleteBulkResponder( public async Task RespondAsync(IMessageDeleteBulk evt, CancellationToken ct = default) { - var guild = await db.GetGuildAsync(evt.GuildID, ct); + var guild = await db.GetGuildAsync(evt.GuildID, false, ct); if (guild.IsMessageIgnored(evt.ChannelID, null)) return Result.Success; diff --git a/Catalogger.Backend/Bot/Responders/Messages/MessageDeleteResponder.cs b/Catalogger.Backend/Bot/Responders/Messages/MessageDeleteResponder.cs index abfb6fa..21b027d 100644 --- a/Catalogger.Backend/Bot/Responders/Messages/MessageDeleteResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Messages/MessageDeleteResponder.cs @@ -64,7 +64,7 @@ public class MessageDeleteResponder( if (await messageRepository.IsMessageIgnoredAsync(evt.ID.Value, ct)) return Result.Success; - var guild = await db.GetGuildAsync(evt.GuildID, ct); + var guild = await db.GetGuildAsync(evt.GuildID, false, ct); if (guild.IsMessageIgnored(evt.ChannelID, evt.ID)) return Result.Success; diff --git a/Catalogger.Backend/Bot/Responders/Messages/MessageUpdateResponder.cs b/Catalogger.Backend/Bot/Responders/Messages/MessageUpdateResponder.cs index 1a298bd..8287620 100644 --- a/Catalogger.Backend/Bot/Responders/Messages/MessageUpdateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Messages/MessageUpdateResponder.cs @@ -56,7 +56,7 @@ public class MessageUpdateResponder( return Result.Success; } - var guildConfig = await db.GetGuildAsync(msg.GuildID.Value, ct); + var guildConfig = await db.GetGuildAsync(msg.GuildID.Value, false, ct); if (await messageRepository.IsMessageIgnoredAsync(msg.ID.Value, ct)) { diff --git a/Catalogger.Backend/Bot/Responders/Roles/RoleCreateResponder.cs b/Catalogger.Backend/Bot/Responders/Roles/RoleCreateResponder.cs index ee0a38f..2933f60 100644 --- a/Catalogger.Backend/Bot/Responders/Roles/RoleCreateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Roles/RoleCreateResponder.cs @@ -39,7 +39,7 @@ public class RoleCreateResponder( _logger.Debug("Received new role {RoleId} in guild {GuildId}", evt.Role.ID, evt.GuildID); roleCache.Set(evt.Role, evt.GuildID); - var guildConfig = await db.GetGuildAsync(evt.GuildID, ct); + var guildConfig = await db.GetGuildAsync(evt.GuildID, false, ct); var embed = new EmbedBuilder() .WithTitle("Role created") diff --git a/Catalogger.Backend/Bot/Responders/Roles/RoleDeleteResponder.cs b/Catalogger.Backend/Bot/Responders/Roles/RoleDeleteResponder.cs index 3206e62..48baef8 100644 --- a/Catalogger.Backend/Bot/Responders/Roles/RoleDeleteResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Roles/RoleDeleteResponder.cs @@ -47,7 +47,7 @@ public class RoleDeleteResponder( return Result.Success; } - var guildConfig = await db.GetGuildAsync(evt.GuildID, ct); + var guildConfig = await db.GetGuildAsync(evt.GuildID, false, ct); var embed = new EmbedBuilder() .WithTitle($"Role \"{role.Name}\" deleted") diff --git a/Catalogger.Backend/Bot/Responders/Roles/RoleUpdateResponder.cs b/Catalogger.Backend/Bot/Responders/Roles/RoleUpdateResponder.cs index ccbdd35..68942e7 100644 --- a/Catalogger.Backend/Bot/Responders/Roles/RoleUpdateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Roles/RoleUpdateResponder.cs @@ -95,7 +95,7 @@ public class RoleUpdateResponder( if (embed.Fields.Count == 0) return Result.Success; - var guildConfig = await db.GetGuildAsync(evt.GuildID, ct); + var guildConfig = await db.GetGuildAsync(evt.GuildID, false, ct); webhookExecutor.QueueLog( guildConfig, LogChannelType.GuildRoleUpdate, diff --git a/Catalogger.Backend/Database/Queries/MessageRepository.cs b/Catalogger.Backend/Database/Queries/MessageRepository.cs index 1ffc21e..e8bb338 100644 --- a/Catalogger.Backend/Database/Queries/MessageRepository.cs +++ b/Catalogger.Backend/Database/Queries/MessageRepository.cs @@ -94,7 +94,10 @@ public class MessageRepository( msg.Attachments.Select(a => new Attachment(a.Filename, a.Size, a.ContentType.Value)) ); - var dbMsg = await db.Messages.FindAsync(msg.ID.Value); + var dbMsg = await db.Messages.FindAsync( + new object?[] { msg.ID.Value }, + cancellationToken: ct + ); if (dbMsg == null) throw new CataloggerError( "Message was null despite HasProxyInfoAsync returning true" @@ -127,7 +130,7 @@ public class MessageRepository( { _logger.Debug("Retrieving message {MessageId}", id); - var dbMsg = await db.Messages.FindAsync(id); + var dbMsg = await db.Messages.AsNoTracking().FirstOrDefaultAsync(m => m.Id == id, ct); if (dbMsg == null) return null; @@ -159,7 +162,8 @@ public class MessageRepository( _logger.Debug("Checking if message {MessageId} has proxy information", id); var msg = await db - .Messages.Select(m => new { m.Id, m.OriginalId }) + .Messages.AsNoTracking() + .Select(m => new { m.Id, m.OriginalId }) .FirstOrDefaultAsync(m => m.Id == id); return (msg != null, msg?.OriginalId != null); } @@ -195,7 +199,8 @@ public class MessageRepository( public async Task IsMessageIgnoredAsync(ulong id, CancellationToken ct = default) { _logger.Debug("Checking if message {MessageId} is ignored", id); - return await db.IgnoredMessages.FirstOrDefaultAsync(m => m.Id == id, ct) != null; + return await db.IgnoredMessages.AsNoTracking().FirstOrDefaultAsync(m => m.Id == id, ct) + != null; } public const int MaxMessageAgeDays = 15; diff --git a/Catalogger.Backend/Database/Queries/QueryExtensions.cs b/Catalogger.Backend/Database/Queries/QueryExtensions.cs index 396fbad..128a184 100644 --- a/Catalogger.Backend/Database/Queries/QueryExtensions.cs +++ b/Catalogger.Backend/Database/Queries/QueryExtensions.cs @@ -15,6 +15,7 @@ using Catalogger.Backend.Database.Models; using Catalogger.Backend.Extensions; +using Microsoft.EntityFrameworkCore; using Remora.Rest.Core; namespace Catalogger.Backend.Database.Queries; @@ -24,22 +25,30 @@ public static class QueryExtensions public static async ValueTask GetGuildAsync( this DatabaseContext db, Snowflake id, + bool shouldTrack = true, CancellationToken ct = default - ) => await db.GetGuildAsync(id.ToUlong(), ct); + ) => await db.GetGuildAsync(id.ToUlong(), shouldTrack, ct); public static async ValueTask GetGuildAsync( this DatabaseContext db, Optional id, + bool shouldTrack = true, CancellationToken ct = default - ) => await db.GetGuildAsync(id.ToUlong(), ct); + ) => await db.GetGuildAsync(id.ToUlong(), shouldTrack, ct); public static async ValueTask GetGuildAsync( this DatabaseContext db, ulong id, + bool shouldTrack = true, CancellationToken ct = default ) { - var guild = await db.Guilds.FindAsync([id], ct); + Guild? guild; + if (shouldTrack) + guild = await db.Guilds.FindAsync([id], ct); + else + guild = await db.Guilds.AsNoTracking().FirstOrDefaultAsync(g => g.Id == id, ct); + if (guild == null) throw new CataloggerError("Guild not found, was not initialized during guild create"); return guild; @@ -50,5 +59,8 @@ public static class QueryExtensions Snowflake guildId, Snowflake userId, CancellationToken ct = default - ) => await db.Watchlists.FindAsync([guildId.Value, userId.Value], ct); + ) => + await db + .Watchlists.AsNoTracking() + .FirstOrDefaultAsync(w => w.GuildId == guildId.Value && w.UserId == userId.Value, ct); }