don't track EFCore objects that don't need to be updated

This commit is contained in:
sam 2024-10-25 16:04:01 +02:00
parent d42e73699b
commit f7f88ff98f
Signed by: sam
GPG key ID: 5F3C3C1B3166639D
24 changed files with 50 additions and 33 deletions

View file

@ -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 = var logChannelId =
webhookExecutor.GetLogChannel(guildConfig, LogChannelType.GuildUpdate) webhookExecutor.GetLogChannel(guildConfig, LogChannelType.GuildUpdate)
?? webhookExecutor.GetLogChannel(guildConfig, LogChannelType.GuildMemberRemove); ?? webhookExecutor.GetLogChannel(guildConfig, LogChannelType.GuildMemberRemove);

View file

@ -70,7 +70,7 @@ public partial class GuildsController(
{ {
var (guildId, guild) = await ParseGuildAsync(id); var (guildId, guild) = await ParseGuildAsync(id);
var guildConfig = await db.GetGuildAsync(guildId.Value); var guildConfig = await db.GetGuildAsync(guildId.Value, false);
var channels = channelCache var channels = channelCache
.GuildChannels(guildId) .GuildChannels(guildId)

View file

@ -227,7 +227,7 @@ public class MetaCommands(
try 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}"); var resp = await _client.GetAsync($"http://localhost:9090/api/v1/query?query={query}");
resp.EnsureSuccessStatusCode(); resp.EnsureSuccessStatusCode();

View file

@ -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( webhookExecutor.QueueLog(
guildConfig, guildConfig,
LogChannelType.ChannelCreate, LogChannelType.ChannelCreate,

View file

@ -49,7 +49,7 @@ public class ChannelDeleteResponder(
return Result.Success; 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() var embed = new EmbedBuilder()
.WithTitle("Channel deleted") .WithTitle("Channel deleted")
.WithColour(DiscordUtils.Red) .WithColour(DiscordUtils.Red)

View file

@ -49,7 +49,7 @@ public class ChannelUpdateResponder(
return Result.Success; 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() var builder = new EmbedBuilder()
.WithTitle( .WithTitle(

View file

@ -38,7 +38,7 @@ public class GuildBanAddResponder(
public async Task<Result> RespondAsync(IGuildBanAdd evt, CancellationToken ct = default) public async Task<Result> 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 // Delay 2 seconds for the audit log
await Task.Delay(2000, ct); await Task.Delay(2000, ct);

View file

@ -38,7 +38,7 @@ public class GuildBanRemoveResponder(
public async Task<Result> RespondAsync(IGuildBanRemove evt, CancellationToken ct = default) public async Task<Result> 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 // Delay 2 seconds for the audit log
await Task.Delay(2000, ct); await Task.Delay(2000, ct);

View file

@ -111,7 +111,7 @@ public class GuildEmojisUpdateResponder(
return Result.Success; 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); webhookExecutor.QueueLog(guildConfig, LogChannelType.GuildEmojisUpdate, embed);
return Result.Success; return Result.Success;
} }

View file

@ -97,7 +97,7 @@ public class GuildUpdateResponder(
if (embed.Fields.Count != 0) if (embed.Fields.Count != 0)
{ {
var guildConfig = await db.GetGuildAsync(evt.ID, ct); var guildConfig = await db.GetGuildAsync(evt.ID, false, ct);
webhookExecutor.QueueLog( webhookExecutor.QueueLog(
guildConfig, guildConfig,
LogChannelType.GuildUpdate, LogChannelType.GuildUpdate,

View file

@ -74,7 +74,7 @@ public class InviteCreateResponder(
inline: true inline: true
); );
var guildConfig = await db.GetGuildAsync(guildId, ct); var guildConfig = await db.GetGuildAsync(guildId, false, ct);
webhookExecutor.QueueLog( webhookExecutor.QueueLog(
guildConfig, guildConfig,
LogChannelType.InviteCreate, LogChannelType.InviteCreate,

View file

@ -89,7 +89,7 @@ public class InviteDeleteResponder(
inline: true inline: true
); );
var guildConfig = await db.GetGuildAsync(guildId, ct); var guildConfig = await db.GetGuildAsync(guildId, false, ct);
webhookExecutor.QueueLog( webhookExecutor.QueueLog(
guildConfig, guildConfig,
LogChannelType.InviteDelete, LogChannelType.InviteDelete,

View file

@ -62,7 +62,7 @@ public class GuildMemberAddResponder(
.WithCurrentTimestamp() .WithCurrentTimestamp()
.WithFooter($"ID: {user.ID}"); .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); var guildRes = await guildApi.GetGuildAsync(member.GuildID, withCounts: true, ct);
if (guildRes.IsSuccess && guildRes.Entity.ApproximateMemberCount.IsDefined()) if (guildRes.IsSuccess && guildRes.Entity.ApproximateMemberCount.IsDefined())
builder.Description += builder.Description +=

View file

@ -50,7 +50,7 @@ public class GuildMemberRemoveResponder(
.WithFooter($"ID: {evt.User.ID}") .WithFooter($"ID: {evt.User.ID}")
.WithCurrentTimestamp(); .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); var member = await memberCache.TryGetAsync(evt.GuildID, evt.User.ID);
if (member == null) if (member == null)

View file

@ -145,7 +145,7 @@ public class GuildMemberUpdateResponder(
.GetOrThrow(); .GetOrThrow();
} }
var guildConfig = await db.GetGuildAsync(newMember.GuildID, ct); var guildConfig = await db.GetGuildAsync(newMember.GuildID, false, ct);
webhookExecutor.QueueLog(guildConfig, LogChannelType.GuildMemberAvatarUpdate, embed); webhookExecutor.QueueLog(guildConfig, LogChannelType.GuildMemberAvatarUpdate, embed);
return Result.Success; 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( webhookExecutor.QueueLog(
guildConfig, guildConfig,
LogChannelType.GuildMemberNickUpdate, LogChannelType.GuildMemberNickUpdate,
@ -253,7 +253,7 @@ public class GuildMemberUpdateResponder(
embed.AddField("Reason", "*(unknown)*"); embed.AddField("Reason", "*(unknown)*");
} }
var guildConfig = await db.GetGuildAsync(member.GuildID, ct); var guildConfig = await db.GetGuildAsync(member.GuildID, false, ct);
webhookExecutor.QueueLog( webhookExecutor.QueueLog(
guildConfig, guildConfig,
LogChannelType.GuildMemberTimeout, LogChannelType.GuildMemberTimeout,
@ -268,7 +268,7 @@ public class GuildMemberUpdateResponder(
CancellationToken ct = default 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 guildRoles = roleCache.GuildRoles(member.GuildID).ToList();
var keyRoleUpdate = new EmbedBuilder() var keyRoleUpdate = new EmbedBuilder()

View file

@ -52,7 +52,7 @@ public class MessageCreateResponder(
return Result.Success; 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, // 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. // and the channel must not be ignored, to store the message.
if (guild.IsMessageIgnored(msg.ChannelID, msg.Author.ID)) if (guild.IsMessageIgnored(msg.ChannelID, msg.Author.ID))

View file

@ -42,7 +42,7 @@ public class MessageDeleteBulkResponder(
public async Task<Result> RespondAsync(IMessageDeleteBulk evt, CancellationToken ct = default) public async Task<Result> 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)) if (guild.IsMessageIgnored(evt.ChannelID, null))
return Result.Success; return Result.Success;

View file

@ -64,7 +64,7 @@ public class MessageDeleteResponder(
if (await messageRepository.IsMessageIgnoredAsync(evt.ID.Value, ct)) if (await messageRepository.IsMessageIgnoredAsync(evt.ID.Value, ct))
return Result.Success; 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)) if (guild.IsMessageIgnored(evt.ChannelID, evt.ID))
return Result.Success; return Result.Success;

View file

@ -56,7 +56,7 @@ public class MessageUpdateResponder(
return Result.Success; 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)) if (await messageRepository.IsMessageIgnoredAsync(msg.ID.Value, ct))
{ {

View file

@ -39,7 +39,7 @@ public class RoleCreateResponder(
_logger.Debug("Received new role {RoleId} in guild {GuildId}", evt.Role.ID, evt.GuildID); _logger.Debug("Received new role {RoleId} in guild {GuildId}", evt.Role.ID, evt.GuildID);
roleCache.Set(evt.Role, 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() var embed = new EmbedBuilder()
.WithTitle("Role created") .WithTitle("Role created")

View file

@ -47,7 +47,7 @@ public class RoleDeleteResponder(
return Result.Success; return Result.Success;
} }
var guildConfig = await db.GetGuildAsync(evt.GuildID, ct); var guildConfig = await db.GetGuildAsync(evt.GuildID, false, ct);
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
.WithTitle($"Role \"{role.Name}\" deleted") .WithTitle($"Role \"{role.Name}\" deleted")

View file

@ -95,7 +95,7 @@ public class RoleUpdateResponder(
if (embed.Fields.Count == 0) if (embed.Fields.Count == 0)
return Result.Success; return Result.Success;
var guildConfig = await db.GetGuildAsync(evt.GuildID, ct); var guildConfig = await db.GetGuildAsync(evt.GuildID, false, ct);
webhookExecutor.QueueLog( webhookExecutor.QueueLog(
guildConfig, guildConfig,
LogChannelType.GuildRoleUpdate, LogChannelType.GuildRoleUpdate,

View file

@ -94,7 +94,10 @@ public class MessageRepository(
msg.Attachments.Select(a => new Attachment(a.Filename, a.Size, a.ContentType.Value)) 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) if (dbMsg == null)
throw new CataloggerError( throw new CataloggerError(
"Message was null despite HasProxyInfoAsync returning true" "Message was null despite HasProxyInfoAsync returning true"
@ -127,7 +130,7 @@ public class MessageRepository(
{ {
_logger.Debug("Retrieving message {MessageId}", id); _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) if (dbMsg == null)
return null; return null;
@ -159,7 +162,8 @@ public class MessageRepository(
_logger.Debug("Checking if message {MessageId} has proxy information", id); _logger.Debug("Checking if message {MessageId} has proxy information", id);
var msg = await db 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); .FirstOrDefaultAsync(m => m.Id == id);
return (msg != null, msg?.OriginalId != null); return (msg != null, msg?.OriginalId != null);
} }
@ -195,7 +199,8 @@ public class MessageRepository(
public async Task<bool> IsMessageIgnoredAsync(ulong id, CancellationToken ct = default) public async Task<bool> IsMessageIgnoredAsync(ulong id, CancellationToken ct = default)
{ {
_logger.Debug("Checking if message {MessageId} is ignored", id); _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; public const int MaxMessageAgeDays = 15;

View file

@ -15,6 +15,7 @@
using Catalogger.Backend.Database.Models; using Catalogger.Backend.Database.Models;
using Catalogger.Backend.Extensions; using Catalogger.Backend.Extensions;
using Microsoft.EntityFrameworkCore;
using Remora.Rest.Core; using Remora.Rest.Core;
namespace Catalogger.Backend.Database.Queries; namespace Catalogger.Backend.Database.Queries;
@ -24,22 +25,30 @@ public static class QueryExtensions
public static async ValueTask<Guild> GetGuildAsync( public static async ValueTask<Guild> GetGuildAsync(
this DatabaseContext db, this DatabaseContext db,
Snowflake id, Snowflake id,
bool shouldTrack = true,
CancellationToken ct = default CancellationToken ct = default
) => await db.GetGuildAsync(id.ToUlong(), ct); ) => await db.GetGuildAsync(id.ToUlong(), shouldTrack, ct);
public static async ValueTask<Guild> GetGuildAsync( public static async ValueTask<Guild> GetGuildAsync(
this DatabaseContext db, this DatabaseContext db,
Optional<Snowflake> id, Optional<Snowflake> id,
bool shouldTrack = true,
CancellationToken ct = default CancellationToken ct = default
) => await db.GetGuildAsync(id.ToUlong(), ct); ) => await db.GetGuildAsync(id.ToUlong(), shouldTrack, ct);
public static async ValueTask<Guild> GetGuildAsync( public static async ValueTask<Guild> GetGuildAsync(
this DatabaseContext db, this DatabaseContext db,
ulong id, ulong id,
bool shouldTrack = true,
CancellationToken ct = default 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) if (guild == null)
throw new CataloggerError("Guild not found, was not initialized during guild create"); throw new CataloggerError("Guild not found, was not initialized during guild create");
return guild; return guild;
@ -50,5 +59,8 @@ public static class QueryExtensions
Snowflake guildId, Snowflake guildId,
Snowflake userId, Snowflake userId,
CancellationToken ct = default 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);
} }