Skip to content
This repository has been archived by the owner on Sep 3, 2024. It is now read-only.

Commit

Permalink
feat: update ready events to handle sharding
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusbegby committed Jul 21, 2023
1 parent 006f2fa commit 184b528
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 17 deletions.
8 changes: 6 additions & 2 deletions src/bot.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require('dotenv').config();
const logger = require('./services/logger');
const { registerEventListeners } = require('./utils/registerEventListeners.js');
const { registerClientCommands } = require('./utils/registerClientCommands.js');
Expand All @@ -8,8 +9,11 @@ const { createPlayer } = require('./utils/factory/createPlayer.js');
const client = await createClient();
const player = await createPlayer(client);

registerEventListeners(client, player);
registerClientCommands(client);
client.on('allShardsReady', async () => {
registerEventListeners(client, player);
registerClientCommands(client);
client.emit('ready', client);
});

client.login(process.env.DISCORD_BOT_TOKEN);
})().catch((error) => {
Expand Down
25 changes: 16 additions & 9 deletions src/events/client/ready.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
const logger = require('../../services/logger');
const { embedOptions, systemOptions, presenceStatusOptions } = require('../../config');
const { Events, EmbedBuilder } = require('discord.js');
const { postBotStats } = require('../../utils/other/postBotStats.js');
const { Events, EmbedBuilder } = require('discord.js');

module.exports = {
name: Events.ClientReady,
isDebug: false,
once: true,
once: false,
execute: async (client) => {
logger.info(`Client logged in successfully as ${client.user.tag}!`);
logger.debug(`Shard ${client.shard.ids[0]}> Client 'ready' event emitted after 'allShardsReady'.`);
await client.user.setPresence(presenceStatusOptions);
await client.user.setPresence(presenceStatusOptions);

// Post bot stats to bot lists in production
process.env.NODE_ENV === 'production' ? postBotStats(client) : null;
const channel = await client.channels.cache.get(systemOptions.systemMessageChannelId);

// send message to system message channel for event
if (systemOptions.systemMessageChannelId) {
await client.channels.cache.get(systemOptions.systemMessageChannelId).send({
// Check if the channel exists in curent shard and send a message
if (channel) {
logger.info(
`Shard ${client.shard.ids[0]}> All shards ready, sending system message to channel id ${channel.id}.`
);
channel.send({
embeds: [
new EmbedBuilder()
.setDescription(`${embedOptions.icons.success} **${client.user.tag}** is now **\`online\`**!`)
.setDescription(
`**${embedOptions.icons.success} All shards ready**\n**${client.user.tag}** is now **\`online\`**!`
)
.setColor(embedOptions.colors.success)
]
});
}

process.env.NODE_ENV === 'production' ? await postBotStats(client) : null;
}
};
13 changes: 11 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
require('dotenv').config();
const logger = require('./services/logger');
const { ShardingManager } = require('discord.js');
const { ShardingManager, ShardEvents } = require('discord.js');

const manager = new ShardingManager('./src/bot.js', {
token: process.env.DISCORD_BOT_TOKEN,
totalShards: 'auto',
totalShards: 2,
shardList: 'auto',
mode: 'process',
respawn: true
});

const readyShards = new Set();
manager.on('shardCreate', (shard) => {
logger.debug(`Launched shard ${shard.id}`);

// When all shards are ready, emit event 'allShardsReady' to all shards
shard.on(ShardEvents.Ready, () => {
readyShards.add(shard.id);
if (readyShards.size === manager.totalShards) {
manager.broadcastEval((client) => client.emit('allShardsReady'));
}
});
});

manager.spawn();
26 changes: 22 additions & 4 deletions src/utils/other/postBotStats.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
const logger = require('../../services/logger');
const https = require('node:https');

exports.postBotStats = (client) => {
exports.postBotStats = async (client) => {
try {
const guildCount = client.guilds.cache.size;
if (client.shard.ids[0] !== 0) {
return logger.debug(`Shard ${client.shard.ids[0]}> Shard is not the first shard, not posting stats.`);
}

logger.debug(
client.shard.ids,
`Shard ${client.shard.ids[0]}> Posting stats to bot lists from client with shard id 0.`
);

let guildCount = 0;

await client.shard
.fetchClientValues('guilds.cache.size')
.then((results) => {
guildCount = results.reduce((acc, guildCount) => acc + guildCount, 0);
})
.catch((error) => {
logger.error(error, `Shard ${client.shard.ids[0]}> Failed to fetch client values from shards.`);
});

/* eslint-disable camelcase */
const sites = [
Expand Down Expand Up @@ -51,7 +69,7 @@ exports.postBotStats = (client) => {
}
];

logger.info(`Posting stats to bot lists with guildCount ${guildCount}...`);
logger.info(`Shard ${client.shard.ids[0]}> Posting stats to bot lists with guildCount ${guildCount}...`);
sites.map((site) => {
let options = {
protocol: 'https:',
Expand All @@ -75,6 +93,6 @@ exports.postBotStats = (client) => {
request.end();
});
} catch (error) {
logger.error(error, 'Failed to post stats to bot lists');
logger.error(error, `Shard ${client.shard.ids[0]}> Failed to post stats to bot lists.`);
}
};

0 comments on commit 184b528

Please sign in to comment.