Several more database-y refactors

- DbConnectionFactory renamed to "Database", will now be the primary entry point for DB stuff
- Created IPKConnection interface mostly containing async extensions to IDbConnection, use this going forward
- Reworked the Connection/Command wrappers (that have performance/logging extensions)
- Probably more stuff that I forgot???
This commit is contained in:
Ske 2020-06-13 18:31:20 +02:00
parent a915ddb41c
commit e176ccbab5
29 changed files with 454 additions and 387 deletions

View file

@ -11,9 +11,9 @@ namespace PluralKit.Bot
{
public class Autoproxy
{
private readonly DbConnectionFactory _db;
private readonly Database _db;
public Autoproxy(DbConnectionFactory db)
public Autoproxy(Database db)
{
_db = db;
}

View file

@ -14,9 +14,9 @@ namespace PluralKit.Bot
{
public class MemberAvatar
{
private readonly DbConnectionFactory _db;
private readonly Database _db;
public MemberAvatar(DbConnectionFactory db)
public MemberAvatar(Database db)
{
_db = db;
}

View file

@ -12,9 +12,9 @@ namespace PluralKit.Bot
public class MemberEdit
{
private readonly IDataStore _data;
private readonly DbConnectionFactory _db;
private readonly Database _db;
public MemberEdit(IDataStore data, DbConnectionFactory db)
public MemberEdit(IDataStore data, Database db)
{
_data = data;
_db = db;

View file

@ -13,9 +13,9 @@ namespace PluralKit.Bot
{
public class ServerConfig
{
private DbConnectionFactory _db;
private Database _db;
private LoggerCleanService _cleanService;
public ServerConfig(LoggerCleanService cleanService, DbConnectionFactory db)
public ServerConfig(LoggerCleanService cleanService, Database db)
{
_cleanService = cleanService;
_db = db;

View file

@ -18,10 +18,10 @@ namespace PluralKit.Bot
public class SystemEdit
{
private IDataStore _data;
private DbConnectionFactory _db;
private Database _db;
private EmbedService _embeds;
public SystemEdit(IDataStore data, EmbedService embeds, DbConnectionFactory db)
public SystemEdit(IDataStore data, EmbedService embeds, Database db)
{
_data = data;
_embeds = embeds;

View file

@ -16,10 +16,10 @@ namespace PluralKit.Bot
public class SystemList
{
private readonly IClock _clock;
private readonly DbConnectionFactory _db;
private readonly Database _db;
private readonly ILogger _logger;
public SystemList(DbConnectionFactory db, ILogger logger, IClock clock)
public SystemList(Database db, ILogger logger, IClock clock)
{
_db = db;
_logger = logger;

View file

@ -22,12 +22,12 @@ namespace PluralKit.Bot
private readonly IMetrics _metrics;
private readonly ProxyService _proxy;
private readonly ILifetimeScope _services;
private readonly DbConnectionFactory _db;
private readonly Database _db;
private readonly IDataStore _data;
public MessageCreated(LastMessageCacheService lastMessageCache, LoggerCleanService loggerClean,
IMetrics metrics, ProxyService proxy, DiscordShardedClient client,
CommandTree tree, ILifetimeScope services, DbConnectionFactory db, IDataStore data)
CommandTree tree, ILifetimeScope services, Database db, IDataStore data)
{
_lastMessageCache = lastMessageCache;
_loggerClean = loggerClean;

View file

@ -11,9 +11,9 @@ namespace PluralKit.Bot
{
private readonly LastMessageCacheService _lastMessageCache;
private readonly ProxyService _proxy;
private readonly DbConnectionFactory _db;
private readonly Database _db;
public MessageEdited(LastMessageCacheService lastMessageCache, ProxyService proxy, DbConnectionFactory db)
public MessageEdited(LastMessageCacheService lastMessageCache, ProxyService proxy, Database db)
{
_lastMessageCache = lastMessageCache;
_proxy = proxy;

View file

@ -21,14 +21,14 @@ namespace PluralKit.Bot
public static readonly TimeSpan MessageDeletionDelay = TimeSpan.FromMilliseconds(1000);
private readonly LogChannelService _logChannel;
private readonly DbConnectionFactory _db;
private readonly Database _db;
private readonly IDataStore _data;
private readonly ILogger _logger;
private readonly WebhookExecutorService _webhookExecutor;
private readonly ProxyMatcher _matcher;
public ProxyService(LogChannelService logChannel, IDataStore data, ILogger logger,
WebhookExecutorService webhookExecutor, DbConnectionFactory db, ProxyMatcher matcher)
WebhookExecutorService webhookExecutor, Database db, ProxyMatcher matcher)
{
_logChannel = logChannel;
_data = data;
@ -43,7 +43,8 @@ namespace PluralKit.Bot
if (!ShouldProxy(message, ctx)) return false;
// Fetch members and try to match to a specific member
var members = (await _db.Execute(c => c.QueryProxyMembers(message.Author.Id, message.Channel.GuildId))).ToList();
await using var conn = await _db.Obtain();
var members = (await conn.QueryProxyMembers(message.Author.Id, message.Channel.GuildId)).ToList();
if (!_matcher.TryMatch(ctx, members, out var match, message.Content, message.Attachments.Count > 0,
allowAutoproxy)) return false;
@ -52,7 +53,7 @@ namespace PluralKit.Bot
if (!CheckProxyNameBoundsOrError(match.Member.ProxyName(ctx))) return false;
// Everything's in order, we can execute the proxy!
await ExecuteProxy(message, ctx, match);
await ExecuteProxy(conn, message, ctx, match);
return true;
}
@ -78,29 +79,39 @@ namespace PluralKit.Bot
return true;
}
private async Task ExecuteProxy(DiscordMessage trigger, MessageContext ctx, ProxyMatch match)
private async Task ExecuteProxy(IPKConnection conn, DiscordMessage trigger, MessageContext ctx,
ProxyMatch match)
{
// Send the webhook
var id = await _webhookExecutor.ExecuteWebhook(trigger.Channel, match.Member.ProxyName(ctx),
match.Member.ProxyAvatar(ctx),
match.Content, trigger.Attachments);
// Handle post-proxy actions
await _data.AddMessage(trigger.Author.Id, trigger.Channel.GuildId, trigger.Channel.Id, id, trigger.Id,
match.Member.Id);
await _logChannel.LogMessage(ctx, match, trigger, id);
// Wait a second or so before deleting the original message
await Task.Delay(MessageDeletionDelay);
try
Task SaveMessage() => _data.AddMessage(conn, trigger.Author.Id, trigger.Channel.GuildId, trigger.Channel.Id, id, trigger.Id, match.Member.Id);
Task LogMessage() => _logChannel.LogMessage(ctx, match, trigger, id).AsTask();
async Task DeleteMessage()
{
await trigger.DeleteAsync();
}
catch (NotFoundException)
{
// If it's already deleted, we just log and swallow the exception
_logger.Warning("Attempted to delete already deleted proxy trigger message {Message}", trigger.Id);
// Wait a second or so before deleting the original message
await Task.Delay(MessageDeletionDelay);
try
{
await trigger.DeleteAsync();
}
catch (NotFoundException)
{
// If it's already deleted, we just log and swallow the exception
_logger.Warning("Attempted to delete already deleted proxy trigger message {Message}", trigger.Id);
}
}
// Run post-proxy actions (simultaneously; order doesn't matter)
// Note that only AddMessage is using our passed-in connection, careful not to pass it elsewhere and run into conflicts
await Task.WhenAll(
DeleteMessage(),
SaveMessage(),
LogMessage()
);
}
private async Task<bool> CheckBotPermissionsOrError(DiscordChannel channel)

View file

@ -16,10 +16,10 @@ namespace PluralKit.Bot {
public class EmbedService
{
private IDataStore _data;
private DbConnectionFactory _db;
private Database _db;
private DiscordShardedClient _client;
public EmbedService(DiscordShardedClient client, IDataStore data, DbConnectionFactory db)
public EmbedService(DiscordShardedClient client, IDataStore data, Database db)
{
_client = client;
_data = data;

View file

@ -14,12 +14,12 @@ using Serilog;
namespace PluralKit.Bot {
public class LogChannelService {
private readonly EmbedService _embed;
private readonly DbConnectionFactory _db;
private readonly Database _db;
private readonly IDataStore _data;
private readonly ILogger _logger;
private readonly DiscordRestClient _rest;
public LogChannelService(EmbedService embed, ILogger logger, DiscordRestClient rest, DbConnectionFactory db, IDataStore data)
public LogChannelService(EmbedService embed, ILogger logger, DiscordRestClient rest, Database db, IDataStore data)
{
_embed = embed;
_rest = rest;

View file

@ -53,10 +53,10 @@ namespace PluralKit.Bot
.Where(b => b.WebhookName != null)
.ToDictionary(b => b.WebhookName);
private DbConnectionFactory _db;
private Database _db;
private DiscordShardedClient _client;
public LoggerCleanService(DbConnectionFactory db, DiscordShardedClient client)
public LoggerCleanService(Database db, DiscordShardedClient client)
{
_db = db;
_client = client;