From be89f907a0df79b33c3e3828f61b1d9c57104b9b Mon Sep 17 00:00:00 2001 From: spiral Date: Wed, 23 Mar 2022 21:32:18 -0400 Subject: [PATCH] feat: block running commands / proxying when system is being deleted Large systems take way too long to delete, which causes any insert for that system to block a connection, which exhausts the connection pool --- Myriad/Rest/Types/Requests/MessageRequest.cs | 2 ++ PluralKit.Bot/Handlers/MessageCreated.cs | 13 +++++++++++++ PluralKit.Core/Database/Functions/MessageContext.cs | 5 +++++ PluralKit.Core/Database/Functions/functions.sql | 2 ++ PluralKit.Core/Database/Migrations/29.sql | 5 +++++ .../Database/Repository/ModelRepository.System.cs | 5 +++-- PluralKit.Core/Database/Utils/DatabaseMigrator.cs | 2 +- 7 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 PluralKit.Core/Database/Migrations/29.sql diff --git a/Myriad/Rest/Types/Requests/MessageRequest.cs b/Myriad/Rest/Types/Requests/MessageRequest.cs index 80506f64..c218c0fd 100644 --- a/Myriad/Rest/Types/Requests/MessageRequest.cs +++ b/Myriad/Rest/Types/Requests/MessageRequest.cs @@ -10,4 +10,6 @@ public record MessageRequest public AllowedMentions? AllowedMentions { get; set; } public Embed[]? Embeds { get; set; } public MessageComponent[]? Components { get; set; } + public Message.Reference? MessageReference { get; set; } + } \ No newline at end of file diff --git a/PluralKit.Bot/Handlers/MessageCreated.cs b/PluralKit.Bot/Handlers/MessageCreated.cs index 68f32b17..0ca4250d 100644 --- a/PluralKit.Bot/Handlers/MessageCreated.cs +++ b/PluralKit.Bot/Handlers/MessageCreated.cs @@ -120,6 +120,17 @@ public class MessageCreated: IEventHandler if (!HasCommandPrefix(content, ourUserId, out var cmdStart) || cmdStart == content.Length) return false; + if (ctx.IsDeleting) + { + await _rest.CreateMessage(evt.ChannelId, new() + { + Content = $"{Emojis.Error} Your system is currently being deleted." + + " Due to database issues, it is not possible to use commands while a system is being deleted. Please wait a few minutes and try again.", + MessageReference = new(guild?.Id, channel.Id, evt.Id) + }); + return true; + } + // Trim leading whitespace from command without actually modifying the string // This just moves the argPos pointer by however much whitespace is at the start of the post-argPos string var trimStartLengthDiff = @@ -164,6 +175,8 @@ public class MessageCreated: IEventHandler private async ValueTask TryHandleProxy(MessageCreateEvent evt, Guild guild, Channel channel, MessageContext ctx) { + if (ctx.IsDeleting) return false; + var botPermissions = await _cache.PermissionsIn(channel.Id); try diff --git a/PluralKit.Core/Database/Functions/MessageContext.cs b/PluralKit.Core/Database/Functions/MessageContext.cs index ef4e6daa..a03cb9da 100644 --- a/PluralKit.Core/Database/Functions/MessageContext.cs +++ b/PluralKit.Core/Database/Functions/MessageContext.cs @@ -10,6 +10,11 @@ namespace PluralKit.Core; public class MessageContext { public SystemId? SystemId { get; } + + /// + /// Whether a system is being deleted (no actions should be taken, or commands ran) + /// + public bool IsDeleting { get; } public ulong? LogChannel { get; } public bool InBlacklist { get; } public bool InLogBlacklist { get; } diff --git a/PluralKit.Core/Database/Functions/functions.sql b/PluralKit.Core/Database/Functions/functions.sql index 3c7857fe..32c8a28c 100644 --- a/PluralKit.Core/Database/Functions/functions.sql +++ b/PluralKit.Core/Database/Functions/functions.sql @@ -1,6 +1,7 @@ create function message_context(account_id bigint, guild_id bigint, channel_id bigint) returns table ( system_id int, + is_deleting bool, log_channel bigint, in_blacklist bool, in_log_blacklist bool, @@ -27,6 +28,7 @@ as $$ guild as (select * from servers where id = guild_id) select system.id as system_id, + system.is_deleting, guild.log_channel, (channel_id = any(guild.blacklist)) as in_blacklist, (channel_id = any(guild.log_blacklist)) as in_log_blacklist, diff --git a/PluralKit.Core/Database/Migrations/29.sql b/PluralKit.Core/Database/Migrations/29.sql new file mode 100644 index 00000000..b83528a4 --- /dev/null +++ b/PluralKit.Core/Database/Migrations/29.sql @@ -0,0 +1,5 @@ +-- schema version 29 + +alter table systems add column is_deleting bool default false; + +update info set schema_version = 29; \ No newline at end of file diff --git a/PluralKit.Core/Database/Repository/ModelRepository.System.cs b/PluralKit.Core/Database/Repository/ModelRepository.System.cs index bfaa31d2..96e554ea 100644 --- a/PluralKit.Core/Database/Repository/ModelRepository.System.cs +++ b/PluralKit.Core/Database/Repository/ModelRepository.System.cs @@ -142,10 +142,11 @@ public partial class ModelRepository }); } - public Task DeleteSystem(SystemId id) + public async Task DeleteSystem(SystemId id) { + await _db.Execute(c => c.QueryAsync("update systems set is_deleting = true where id = @id", new { id = id })); var query = new Query("systems").AsDelete().Where("id", id); + await _db.ExecuteQuery(query); _logger.Information("Deleted {SystemId}", id); - return _db.ExecuteQuery(query); } } \ No newline at end of file diff --git a/PluralKit.Core/Database/Utils/DatabaseMigrator.cs b/PluralKit.Core/Database/Utils/DatabaseMigrator.cs index 26eff955..029cd550 100644 --- a/PluralKit.Core/Database/Utils/DatabaseMigrator.cs +++ b/PluralKit.Core/Database/Utils/DatabaseMigrator.cs @@ -9,7 +9,7 @@ namespace PluralKit.Core; internal class DatabaseMigrator { private const string RootPath = "PluralKit.Core.Database"; // "resource path" root for SQL files - private const int TargetSchemaVersion = 28; + private const int TargetSchemaVersion = 29; private readonly ILogger _logger; public DatabaseMigrator(ILogger logger)