From 88c7c3fbde0e669ed2e015ccc3b15700cf52119d Mon Sep 17 00:00:00 2001 From: "Navy.gif" Date: Thu, 28 Mar 2024 11:34:53 +0200 Subject: [PATCH] Should fix graceful exits --- src/client/DiscordClient.ts | 8 +- src/client/components/MusicPlayer.ts | 126 +++++++++++++-------------- src/middleware/Controller.ts | 15 ++-- src/middleware/Shard.ts | 1 - 4 files changed, 80 insertions(+), 70 deletions(-) diff --git a/src/client/DiscordClient.ts b/src/client/DiscordClient.ts index 2073dce..3168185 100644 --- a/src/client/DiscordClient.ts +++ b/src/client/DiscordClient.ts @@ -67,7 +67,7 @@ class DiscordClient extends Client this.#logger.error(`Unhandled rejection:\n${err?.stack || err}`); }); - // process.on('message', this.#handleMessage.bind(this)); + process.on('message', this.#handleMessage.bind(this)); process.on('SIGINT', () => this.shutdown()); process.on('SIGTERM', () => this.shutdown()); @@ -115,6 +115,12 @@ class DiscordClient extends Client process.exit(code); } + #handleMessage (message: IPCMessage) + { + if (message._shutdown) + this.shutdown(); + } + async sendSplitMessage (message: Message, text: string, opts: MessageReplyOptions) { const words = text.split(' '); diff --git a/src/client/components/MusicPlayer.ts b/src/client/components/MusicPlayer.ts index 99c731f..e1e6ef1 100644 --- a/src/client/components/MusicPlayer.ts +++ b/src/client/components/MusicPlayer.ts @@ -59,19 +59,47 @@ class MusicPlayer implements Initialisable this.#player.on('error', (err) => this.#logger.error(err)); } - get ready () + async initialise () { - return this.#ready; + if (this.ready) + return; + this.#logger.info('Initialising music player'); + + if (fs.existsSync(cachePath)) + { + const rawConfig = fs.readFileSync(cachePath, { encoding: 'utf-8' }); + const config = JSON.parse(rawConfig); + this.#volume = config.volume; + this.#queue = config.queue; + } + await this.#library.initialise(); + + this.#shuffleList = this.#library.getShufflePlaylist(); + + this.#initialiseVoiceChannels(); + + this.#ready = true; + this.playNext(); } - get library () + stop (): void | Promise { - return this.#library; - } + this.#ready = false; + this.#logger.info('Stopping music player'); + this.#logger.info('Disconnecting all guilds'); + for (const [ guildId, { connection, subscription }] of this.#connections) + { + this.#logger.debug(`Disconnecting ${guildId}`); + subscription.unsubscribe(); + connection.disconnect(); + } + this.#library.stop(); - get queue () - { - return Object.freeze(this.#queue); + const config = { + volume: this.#volume, + queue: this.#queue + }; + fs.writeFileSync(cachePath, JSON.stringify(config)); } async request (keyword: string) @@ -178,61 +206,6 @@ class MusicPlayer implements Initialisable } - get volume () - { - return this.#volume * 100; - } - - set volume (vol: number) - { - vol /= 100; - this.#volume = vol; - this.#currentResource.volume?.setVolume(vol); - } - - stop (): void | Promise - { - this.#ready = false; - this.#logger.info('Stopping music player'); - this.#logger.info('Disconnecting all guilds'); - for (const [ guildId, { connection, subscription }] of this.#connections) - { - this.#logger.debug(`Disconnecting ${guildId}`); - subscription.unsubscribe(); - connection.disconnect(); - } - this.#library.stop(); - - const config = { - volume: this.#volume, - queue: this.#queue - }; - fs.writeFileSync(cachePath, JSON.stringify(config)); - } - - async initialise () - { - if (this.ready) - return; - this.#logger.info('Initialising music player'); - - if (fs.existsSync(cachePath)) - { - const rawConfig = fs.readFileSync(cachePath, { encoding: 'utf-8' }); - const config = JSON.parse(rawConfig); - this.#volume = config.volume; - this.#queue = config.queue; - } - await this.#library.initialise(); - - this.#shuffleList = this.#library.getShufflePlaylist(); - - this.#initialiseVoiceChannels(); - - this.#ready = true; - this.playNext(); - } - #initialiseVoiceChannels () { for (const config of this.#options.guilds) @@ -322,6 +295,33 @@ class MusicPlayer implements Initialisable // return; } + get volume () + { + return this.#volume * 100; + } + + set volume (vol: number) + { + vol /= 100; + this.#volume = vol; + this.#currentResource.volume?.setVolume(vol); + } + + get ready () + { + return this.#ready; + } + + get library () + { + return this.#library; + } + + get queue () + { + return Object.freeze(this.#queue); + } + } export default MusicPlayer; \ No newline at end of file diff --git a/src/middleware/Controller.ts b/src/middleware/Controller.ts index 3e435d6..3c16675 100644 --- a/src/middleware/Controller.ts +++ b/src/middleware/Controller.ts @@ -52,8 +52,8 @@ class Controller this.#ready = false; this.#exiting = false; - process.on('SIGINT', this.shutdown.bind(this)); - process.on('SIGTERM', this.shutdown.bind(this)); + process.on('SIGINT', () => this.shutdown('SIGINT')); + process.on('SIGTERM', () => this.shutdown('SIGTERM')); } async build () @@ -234,7 +234,7 @@ class Controller return { shardList, totalShards, execArgv }; } - async shutdown () + async shutdown (type: string) { if (this.#exiting) return; @@ -243,8 +243,13 @@ class Controller setTimeout(process.exit, 90_000); const promises = this.#shards .filter(shard => shard.ready) - .map(shard => shard.awaitShutdown() - .then(() => shard.removeAllListeners())); + .map(shard => + { + if (type === 'SIGTERM') + return shard.kill(); + return shard.awaitShutdown() + .then(() => shard.removeAllListeners()); + }); if (promises.length) await Promise.all(promises); this.#logger.status('Shutdown complete, goodbye'); diff --git a/src/middleware/Shard.ts b/src/middleware/Shard.ts index d28e373..9a17a60 100644 --- a/src/middleware/Shard.ts +++ b/src/middleware/Shard.ts @@ -206,7 +206,6 @@ class Shard extends EventEmitter }); this.send({ _shutdown: true }); - }); } return Promise.resolve();