Additional information

TIP

This page is a follow-up and bases its code on the previous page.

Here are some extra topics covered about sharding that might have raised concerns.

Legend

  • manager is an instance of ShardingManager, e.g. const manager = new ShardingManager(file, options);
  • client.shard refers to the current shard.

Shard messages

For shards to communicate, they have to send messages to one another, as they each have another process. You must wait for each shard to finish spawning before you can listen to their events, otherwise ShardingManager#shards will be an empty Collection. You can listen for these messages on the individual shards by adding the following lines in your index.js file:

manager.spawn()
	.then(shards => {
		shards.forEach(shard => {
			shard.on('message', message => {
				console.log(`Shard[${shard.id}] : ${message._eval} : ${message._result}`);
			});
		});
	})
	.catch(console.error);
1
2
3
4
5
6
7
8
9

As the property names imply, the _eval property is what the shard is attempting to evaluate, and the _result property is the output of said evaluation. However, these properties are only guaranteed if a shard is sending a message. There will also be an _error property, should the evaluation have thrown an error.

You can also send messages via process.send('hello'), which would not contain the same information. This is why the .message property's type is declared as * in the Shard#event:messageopen in new window documentation.

Specific shards

There might be times where you want to target a specific shard. An example would be to kill a specific shard that isn't working as intended. You can achieve this by taking the following snippet (in a command, preferably):

TIP

In discord.js v13, Client#shardopen in new window can hold multiple ids. If you use the default sharding manager, the .ids array will only have one entry.

client.shard.broadcastEval(c => {
	if (c.shard.ids.includes(0)) process.exit();
});
1
2
3

If you're using something like PM2open in new window or Foreveropen in new window, this is an easy way to restart a specific shard. Remember, ShardClientUtil#broadcastEval()open in new window sends a message to all shards, so you have to check if it's on the shard you want.

ShardingManager#shardArgs and ShardingManager#execArgv

Consider the following example of creating a new ShardingManager instance:

const manager = new ShardingManager('./bot.js', {
	execArgv: ['--trace-warnings'],
	shardArgs: ['--ansi', '--color'],
	token: 'your-token-goes-here',
});
1
2
3
4
5

The execArgv property is what you would usually pass to Node without sharding, e.g.:

node --trace-warnings bot.js
1

You can find a list of command-line options for Node hereopen in new window.

The shardArgs property is what you would usually pass to your bot without sharding, e.g.:

node bot.js --ansi --color
1

You can access them later as usual via process.argv, which contains an array of executables, your main file, and the command-line arguments used to execute the script.

Eval arguments

There may come the point where you will want to pass arguments from the outer scope into a .broadcastEval() call.

function funcName(c, { arg }) {
	// ...
}

client.shard.broadcastEval(funcName, { context: { arg: 'arg' } });
1
2
3
4
5

The BroadcastEvalOptionsopen in new window typedef was introduced in discord.js v13 as the second parameter in .broadcastEval(). It accepts two properties: shard and context. The context property will be sent as the second argument to your function.

In this small snippet, an argument is passed to the funcName function through this parameter. The function will recieve the arguments as an object as the second parameter.

WARNING

The context option only accepts properties which are JSON-serializable. This means you cannot pass complex data types in the context directly. For example, if you sent a User instance, the function would recieve the raw data object.