From a517ca3906f11093469cc4792a06bd8b5011aefa Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Mon, 22 Jul 2019 00:10:54 +0300 Subject: [PATCH] Add temporary config auto-reload --- src/data/Configs.ts | 13 ++++++++ src/plugins/GuildConfigReloader.ts | 51 ++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/plugins/GuildConfigReloader.ts diff --git a/src/data/Configs.ts b/src/data/Configs.ts index 5cb0a700..236713a4 100644 --- a/src/data/Configs.ts +++ b/src/data/Configs.ts @@ -28,6 +28,19 @@ export class Configs extends BaseRepository { }); } + async getHighestId(): Promise { + const rows = await connection.query("SELECT MAX(id) AS highest_id FROM configs"); + return (rows.length && rows[0].highest_id) || 0; + } + + getActiveLargerThanId(id) { + return this.configs + .createQueryBuilder() + .where("id > :id", { id }) + .andWhere("is_active = 1") + .getMany(); + } + async hasConfig(key) { return (await this.getActiveByKey(key)) != null; } diff --git a/src/plugins/GuildConfigReloader.ts b/src/plugins/GuildConfigReloader.ts new file mode 100644 index 00000000..2fd82e5c --- /dev/null +++ b/src/plugins/GuildConfigReloader.ts @@ -0,0 +1,51 @@ +import moment from "moment-timezone"; +import { ZeppelinPlugin } from "./ZeppelinPlugin"; +import { Configs } from "../data/Configs"; +import { logger } from "knub"; +import { GlobalZeppelinPlugin } from "./GlobalZeppelinPlugin"; +import { DBDateFormat } from "../utils"; + +const CHECK_INTERVAL = 1000; + +/** + * Temporary solution to reloading guilds when their config changes + * And you know what they say about temporary solutions... + */ +export class GuildConfigReloader extends GlobalZeppelinPlugin { + public static pluginName = "guild_config_reloader"; + protected guildConfigs: Configs; + private unloaded = false; + private highestConfigId; + private nextCheckTimeout; + + async onLoad() { + this.guildConfigs = new Configs(); + + this.highestConfigId = await this.guildConfigs.getHighestId(); + this.reloadChangedGuilds(); + } + + onUnload() { + clearTimeout(this.nextCheckTimeout); + this.unloaded = true; + } + + protected async reloadChangedGuilds() { + if (this.unloaded) return; + + const changedConfigs = await this.guildConfigs.getActiveLargerThanId(this.highestConfigId); + for (const item of changedConfigs) { + if (!item.key.startsWith("guild-")) continue; + + const guildId = item.key.slice("guild-".length); + logger.info(`Config changed, reloading guild ${guildId}`); + await this.knub.reloadGuild(guildId); + + if (item.id > this.highestConfigId) { + this.highestConfigId = item.id; + } + } + + this.nextCheckTimeout = setTimeout(() => this.reloadChangedGuilds(), CHECK_INTERVAL); + } +}