replace channel history calls to use caches

This commit is contained in:
13xforever 2020-09-29 17:31:28 +05:00
parent db013a27f0
commit 5d064708ec
12 changed files with 89 additions and 15 deletions

View File

@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using CompatBot.EventHandlers;
using CompatBot.Utils;
using DSharpPlus.CommandsNext;
using DSharpPlus.CommandsNext.Attributes;
@ -18,7 +19,7 @@ namespace CompatBot.Commands.Attributes
try
{
var msgList = await ctx.Channel.GetMessagesAsync(10).ConfigureAwait(false);
var msgList = await ctx.Channel.GetMessagesCachedAsync(10).ConfigureAwait(false);
if (msgList.Any(m => m.Author.IsCurrent
&& m.Content is string s
&& s.Contains(ctx.Command.QualifiedName, StringComparison.InvariantCultureIgnoreCase)))

View File

@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using CompatBot.EventHandlers;
using CompatBot.Utils;
using DSharpPlus.CommandsNext;
using DSharpPlus.CommandsNext.Attributes;
@ -18,7 +19,7 @@ namespace CompatBot.Commands.Attributes
try
{
var msgList = await ctx.Channel.GetMessagesAsync(10).ConfigureAwait(false);
var msgList = await ctx.Channel.GetMessagesCachedAsync(10).ConfigureAwait(false);
if (msgList.Any(m => m.Author.IsCurrent
&& m.Content is string s
&& s.Contains(ctx.Command.QualifiedName, StringComparison.InvariantCultureIgnoreCase)))

View File

@ -34,7 +34,7 @@ namespace CompatBot.Commands
var sourceTerm = term;
if (string.IsNullOrEmpty(term))
{
var lastBotMessages = await ctx.Channel.GetMessagesBeforeAsync(ctx.Message.Id, 10).ConfigureAwait(false);
var lastBotMessages = await ctx.Channel.GetMessagesBeforeCachedAsync(ctx.Message.Id, 10).ConfigureAwait(false);
var showList = true;
foreach (var pastMsg in lastBotMessages)
if (pastMsg.Embeds.FirstOrDefault() is DiscordEmbed pastEmbed

View File

@ -7,6 +7,7 @@ using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using ColorThiefDotNet;
using CompatBot.EventHandlers;
using CompatBot.Utils;
using CompatBot.Utils.Extensions;
using DSharpPlus;
@ -387,7 +388,7 @@ namespace CompatBot.Commands
&& ctx.Channel.PermissionsFor(ctx.Client.GetMember(ctx.Guild, ctx.Client.CurrentUser)).HasPermission(Permissions.ReadMessageHistory))
try
{
var previousMessages = await ctx.Channel.GetMessagesBeforeAsync(ctx.Message.Id, 10).ConfigureAwait(false);
var previousMessages = await ctx.Channel.GetMessagesBeforeCachedAsync(ctx.Message.Id, 10).ConfigureAwait(false);
var (selectedMsg, selectedAttachment) = (
from m in previousMessages
where m.Attachments?.Count > 0

View File

@ -72,7 +72,7 @@ namespace CompatBot.EventHandlers
try
{
var messages = await channel.GetMessagesAsync(100).ConfigureAwait(false);
var messages = await channel.GetMessagesCachedAsync(100).ConfigureAwait(false);
var messagesToCheck = from msg in messages
where msg.CreationTimestamp > after
select msg;

View File

@ -32,7 +32,7 @@ namespace CompatBot.EventHandlers
if (BotReactionsHandler.NeedToSilence(msg).needToChill)
return;
lastBotMessages = await args.Channel.GetMessagesBeforeAsync(args.Message.Id, Config.ProductCodeLookupHistoryThrottle).ConfigureAwait(false);
lastBotMessages = await args.Channel.GetMessagesBeforeCachedAsync(args.Message.Id, Config.ProductCodeLookupHistoryThrottle).ConfigureAwait(false);
StringBuilder previousRepliesBuilder = null;
foreach (var msg in lastBotMessages)
{

View File

@ -1,9 +1,12 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CompatBot.Utils;
using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using Microsoft.VisualStudio.Services.Common;
namespace CompatBot.EventHandlers
{
@ -12,7 +15,7 @@ namespace CompatBot.EventHandlers
internal static class GlobalMessageCache
{
private static readonly TCache MessageQueue = new TCache();
private static readonly Func<DiscordMessage, ulong> KeyGen = (DiscordMessage m) => m.Id;
private static readonly Func<DiscordMessage, ulong> KeyGen = m => m.Id;
public static Task OnMessageCreated(MessageCreateEventArgs args)
{
@ -20,7 +23,11 @@ namespace CompatBot.EventHandlers
return Task.CompletedTask;
if (!MessageQueue.TryGetValue(args.Channel.Id, out var queue))
MessageQueue[args.Channel.Id] = queue = new FixedLengthBuffer<ulong, DiscordMessage>(KeyGen);
lock (MessageQueue)
{
if (!MessageQueue.TryGetValue(args.Channel.Id, out queue))
MessageQueue[args.Channel.Id] = queue = new FixedLengthBuffer<ulong, DiscordMessage>(KeyGen);
}
lock(queue.syncObj)
queue.Add(args.Message);
@ -69,5 +76,70 @@ namespace CompatBot.EventHandlers
queue.AddOrReplace(args.Message);
return Task.CompletedTask;
}
internal static Task<List<DiscordMessage>> GetMessagesCachedAsync(this DiscordChannel ch, int count = 100)
{
if (!MessageQueue.TryGetValue(ch.Id, out var queue))
lock (MessageQueue)
if (!MessageQueue.TryGetValue(ch.Id, out queue))
MessageQueue[ch.Id] = queue = new FixedLengthBuffer<ulong, DiscordMessage>(KeyGen);
List<DiscordMessage> result;
lock(queue.syncObj)
result = queue.Reverse().Take(count).ToList();
var cacheCount = result.Count;
var fetchCount = Math.Max(count - cacheCount, 0);
if (fetchCount > 0)
{
IReadOnlyList<DiscordMessage> fetchedList;
if (result.Any())
fetchedList = ch.GetMessagesBeforeAsync(result[0].Id, fetchCount).ConfigureAwait(false).GetAwaiter().GetResult();
else
fetchedList = ch.GetMessagesAsync(fetchCount).ConfigureAwait(false).GetAwaiter().GetResult();
result.AddRange(fetchedList);
if (queue.Count < Config.ChannelMessageHistorySize)
lock (queue.syncObj)
{
// items in queue might've changed since the previous check at the beginning of this method
var freshCopy = queue.Reverse().ToList();
queue.Clear();
queue.AddRange(freshCopy.Concat(fetchedList).Distinct().Reverse());
}
}
return Task.FromResult(result);
}
internal static Task<List<DiscordMessage>> GetMessagesBeforeCachedAsync(this DiscordChannel ch, ulong msgId, int count = 100)
{
if (!MessageQueue.TryGetValue(ch.Id, out var queue))
lock (MessageQueue)
if (!MessageQueue.TryGetValue(ch.Id, out queue))
MessageQueue[ch.Id] = queue = new FixedLengthBuffer<ulong, DiscordMessage>(KeyGen);
List<DiscordMessage> result;
lock(queue.syncObj)
result = queue.Reverse().SkipWhile(m => m.Id >= msgId).Take(count).ToList();
var cacheCount = result.Count;
var fetchCount = Math.Max(count - cacheCount, 0);
if (fetchCount > 0)
{
IReadOnlyList<DiscordMessage> fetchedList;
if (result.Any())
{
fetchedList = ch.GetMessagesBeforeAsync(result[0].Id, fetchCount).ConfigureAwait(false).GetAwaiter().GetResult();
if (queue.Count < Config.ChannelMessageHistorySize)
lock (queue.syncObj)
{
// items in queue might've changed since the previous check at the beginning of this method
var freshCopy = queue.Reverse().ToList();
queue.Clear();
queue.AddRange(freshCopy.Concat(fetchedList).Distinct().Reverse());
}
}
else
fetchedList = ch.GetMessagesBeforeAsync(msgId, fetchCount).ConfigureAwait(false).GetAwaiter().GetResult();
result.AddRange(fetchedList);
}
return Task.FromResult(result);
}
}
}

View File

@ -46,7 +46,7 @@ namespace CompatBot.EventHandlers
try
{
var explanation = await GetExplanationAsync(string.IsNullOrEmpty(match.Groups["vulkan"].Value) ? "log" : "vulkan-1").ConfigureAwait(false);
var lastBotMessages = await args.Channel.GetMessagesBeforeAsync(args.Message.Id, 10).ConfigureAwait(false);
var lastBotMessages = await args.Channel.GetMessagesBeforeCachedAsync(args.Message.Id, 10).ConfigureAwait(false);
foreach (var msg in lastBotMessages)
if (BotReactionsHandler.NeedToSilence(msg).needToChill
|| (msg.Author.IsCurrent && msg.Content == explanation.Text))

View File

@ -31,7 +31,7 @@ namespace CompatBot.EventHandlers
if (BotReactionsHandler.NeedToSilence(msg).needToChill)
return;
lastBotMessages = await args.Channel.GetMessagesBeforeAsync(args.Message.Id, Config.ProductCodeLookupHistoryThrottle).ConfigureAwait(false);
lastBotMessages = await args.Channel.GetMessagesBeforeCachedAsync(args.Message.Id, Config.ProductCodeLookupHistoryThrottle).ConfigureAwait(false);
StringBuilder previousRepliesBuilder = null;
foreach (var msg in lastBotMessages)
{

View File

@ -97,7 +97,7 @@ namespace CompatBot.EventHandlers
var checkTasks = new List<Task>();
foreach (var channel in guild.Channels.Values.Where(ch => Config.Moderation.Channels.Contains(ch.Id)))
{
var messages = await channel.GetMessagesAsync().ConfigureAwait(false);
var messages = await channel.GetMessagesCachedAsync().ConfigureAwait(false);
var messagesToCheck = from msg in messages
where msg.CreationTimestamp > after && msg.Reactions.Any(r => r.Emoji == Config.Reactions.Starbucks && r.Count >= Config.Moderation.StarbucksThreshold)
select msg;

View File

@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using CompatApiClient.Utils;
using CompatBot.EventHandlers;
using DSharpPlus;
using DSharpPlus.CommandsNext;
using DSharpPlus.Entities;
@ -106,7 +107,7 @@ namespace CompatBot.Utils
throw new ArgumentException(nameof(timeLimit));
var afterTime = timeLimit ?? DateTime.UtcNow.AddSeconds(-30);
var messages = await channel.GetMessagesBeforeAsync(beforeMessageId, limit).ConfigureAwait(false);
var messages = await channel.GetMessagesBeforeCachedAsync(beforeMessageId, limit).ConfigureAwait(false);
return messages.TakeWhile(m => m.CreationTimestamp > afterTime).ToList().AsReadOnly();
}

View File

@ -60,9 +60,7 @@ namespace CompatBot.Utils
}
public List<TValue> GetOldItems(int count)
{
return keyList.Take(Math.Min(Count, count)).Select(k => lookup[k]).ToList();
}
=> keyList.Take(Math.Min(Count, count)).Select(k => lookup[k]).ToList();
public List<TValue> GetExcess()
{