feat: use redis cache for non-id message lookups

This commit is contained in:
spiral
2022-11-24 06:32:55 +00:00
parent bf7747ab34
commit e9673a6704
9 changed files with 75 additions and 29 deletions

View File

@@ -40,6 +40,7 @@ public class Context
Cache = provider.Resolve<IDiscordCache>();
Database = provider.Resolve<IDatabase>();
Repository = provider.Resolve<ModelRepository>();
Redis = provider.Resolve<RedisService>();
_metrics = provider.Resolve<IMetrics>();
_provider = provider;
_commandMessageService = provider.Resolve<CommandMessageService>();
@@ -74,6 +75,7 @@ public class Context
internal readonly IDatabase Database;
internal readonly ModelRepository Repository;
internal readonly RedisService Redis;
public async Task<Message> Reply(string text = null, Embed embed = null, AllowedMentions? mentions = null)
{

View File

@@ -164,7 +164,7 @@ public class ProxiedMessage
ulong? recent = null;
if (isReproxy)
recent = await ctx.Repository.GetLastMessage(ctx.Guild.Id, ctx.Channel.Id, ctx.Author.Id);
recent = await ctx.Redis.GetLastMessage(ctx.Author.Id, ctx.Channel.Id);
else
recent = await FindRecentMessage(ctx, timeout);
@@ -210,13 +210,13 @@ public class ProxiedMessage
return (msg, member.System);
}
private async Task<PKMessage?> FindRecentMessage(Context ctx, Duration timeout)
private async Task<ulong?> FindRecentMessage(Context ctx, Duration timeout)
{
var lastMessage = await ctx.Repository.GetLastMessage(ctx.Guild.Id, ctx.Channel.Id, ctx.Author.Id);
var lastMessage = await ctx.Redis.GetLastMessage(ctx.Author.Id, ctx.Channel.Id);
if (lastMessage == null)
return null;
var timestamp = DiscordUtils.SnowflakeToInstant(lastMessage.Mid);
var timestamp = DiscordUtils.SnowflakeToInstant(lastMessage.Value);
if (SystemClock.Instance.GetCurrentInstant() - timestamp > timeout)
return null;

View File

@@ -22,6 +22,7 @@ public class ProxyService
private static readonly TimeSpan MessageDeletionDelay = TimeSpan.FromMilliseconds(1000);
private readonly IDiscordCache _cache;
private readonly IDatabase _db;
private readonly RedisService _redis;
private readonly DispatchService _dispatch;
private readonly LastMessageCacheService _lastMessage;
@@ -35,13 +36,14 @@ public class ProxyService
private readonly NodaTime.IClock _clock;
public ProxyService(LogChannelService logChannel, ILogger logger, WebhookExecutorService webhookExecutor,
DispatchService dispatch, IDatabase db, ProxyMatcher matcher, IMetrics metrics, ModelRepository repo,
DispatchService dispatch, IDatabase db, RedisService redis, ProxyMatcher matcher, IMetrics metrics, ModelRepository repo,
NodaTime.IClock clock, IDiscordCache cache, DiscordApiClient rest, LastMessageCacheService lastMessage)
{
_logChannel = logChannel;
_webhookExecutor = webhookExecutor;
_dispatch = dispatch;
_db = db;
_redis = redis;
_matcher = matcher;
_metrics = metrics;
_repo = repo;
@@ -420,6 +422,18 @@ public class ProxyService
Task SaveMessageInDatabase()
=> _repo.AddMessage(sentMessage);
async Task SaveMessageInRedis()
{
// logclean info
await _redis.SetLogCleanup(triggerMessage.Author.Id, triggerMessage.GuildId.Value);
// last message info (edit/reproxy)
await _redis.SetLastMessage(triggerMessage.Author.Id, triggerMessage.ChannelId, sentMessage.Mid);
// "by original mid" lookup
await _redis.SetOriginalMid(triggerMessage.Id, proxyMessage.Id);
}
Task LogMessageToChannel() =>
_logChannel.LogMessage(sentMessage, triggerMessage, proxyMessage).AsTask();
@@ -458,6 +472,7 @@ public class ProxyService
await Task.WhenAll(
DeleteProxyTriggerMessage(),
SaveMessageInDatabase(),
SaveMessageInRedis(),
LogMessageToChannel(),
SaveLatchAutoproxy(),
DispatchWebhook()

View File

@@ -79,12 +79,12 @@ public class LoggerCleanService
private readonly IDiscordCache _cache;
private readonly DiscordApiClient _client;
private readonly IDatabase _db;
private readonly RedisService _redis;
private readonly ILogger _logger;
public LoggerCleanService(IDatabase db, DiscordApiClient client, IDiscordCache cache, ILogger logger)
public LoggerCleanService(RedisService redis, DiscordApiClient client, IDiscordCache cache, ILogger logger)
{
_db = db;
_redis = redis;
_client = client;
_cache = cache;
_logger = logger.ForContext<LoggerCleanService>();
@@ -124,20 +124,10 @@ public class LoggerCleanService
_logger.Debug("Fuzzy logclean for {BotName} on {MessageId}: {@FuzzyExtractResult}",
bot.Name, msg.Id, fuzzy);
var mid = await _db.Execute(conn =>
conn.QuerySingleOrDefaultAsync<ulong?>(
"select mid from messages where sender = @User and mid > @ApproxID and guild = @Guild limit 1",
new
{
fuzzy.Value.User,
Guild = msg.GuildId,
ApproxId = DiscordUtils.InstantToSnowflake(
fuzzy.Value.ApproxTimestamp - Duration.FromSeconds(3))
}));
var exists = await _redis.HasLogCleanup(fuzzy.Value.User, msg.GuildId.Value);
// If we didn't find a corresponding message, bail
if (mid == null)
return;
if (!exists) return;
// Otherwise, we can *reasonably assume* that this is a logged deletion, so delete the log message.
await _client.DeleteMessage(msg.ChannelId, msg.Id);
@@ -151,8 +141,7 @@ public class LoggerCleanService
_logger.Debug("Pure logclean for {BotName} on {MessageId}: {@FuzzyExtractResult}",
bot.Name, msg.Id, extractedId);
var mid = await _db.Execute(conn => conn.QuerySingleOrDefaultAsync<ulong?>(
"select mid from messages where original_mid = @Mid", new { Mid = extractedId.Value }));
var mid = await _redis.GetOriginalMid(extractedId.Value);
if (mid == null) return;
// If we've gotten this far, we found a logged deletion of a trigger message. Just yeet it!