Información adicional
CONSEJO
Esta página es una continuación y basa su código en la página anterior.
Estos son algunos de los temas adicionales tratados sobre sharding que podrían haber despertado inquietudes.
Aspectos
manager
es una instancia deShardingManager
, p.ej.const manager = new ShardingManager(file, options);
client.shard
se refiere al shard actual.
Mensajes de shards
Para que los shards se comuniquen, tienen que enviarse mensajes entre ellos, ya que cada uno tiene otro proceso. Debes esperar a que cada fragmento termine de generarse para poder escuchar sus eventos, de lo contrario ShardingManager#shards
será una Collection
vacía. Puedes escuchar estos mensajes en las shards individuales añadiendo las siguientes líneas en tu archivo index.js
:
manager.spawn()
.then(shards => {
shards.forEach(shard => {
shard.on('message', message => {
console.log(`Shard[${shard.id}] : ${message._eval} : ${message._result}`);
});
});
})
.catch(console.error);
2
3
4
5
6
7
8
9
Como los nombres de las propiedades implican, la propiedad _eval
es lo que el fragmento está intentando evaluar, y la propiedad _result
es el resultado de dicha evaluación. Sin embargo, estas propiedades sólo están garantizadas si un shard está enviando un mensaje. También habrá una propiedad _error
, en caso de que la evaluación haya arrojado un error.
También puede enviar mensajes a través de process.send('hola')
, que no contendría la misma información. Esta es la razón por la que el tipo de la propiedad .message
se declara como *
en la documentación Shard#event:message
open in new window.
Shards específicas
Puede haber ocasiones en las que quieras centrarte en una shard específica. Un ejemplo sería matar una shard en específico que no está funcionando según lo previsto. Puede conseguirlo tomando el siguiente fragmento de código (en un comando, preferiblemente):
CONSEJO
En discord.js v13, Client#shard
open in new window puede contener múltiples ids. Si utilizas el gestor de fragmentación por defecto, el array .ids
sólo tendrá una entrada.
client.shard.broadcastEval(c => {
if (c.shard.ids.includes(0)) process.exit();
});
2
3
Si estás usando algo como PM2open in new window o Foreveropen in new window, esta es una forma fácil de reiniciar un shard específico. Recuerda, ShardClientUtil#broadcastEval()
open in new window envía un mensaje a todos los shards, así que tienes que comprobar si está en el shard que quieres.
ShardingManager#shardArgs
y ShardingManager#execArgv
Considera el siguiente ejemplo de creación de una nueva instancia de ShardingManager
:
const manager = new ShardingManager('./bot.js', {
execArgv: ['--trace-warnings'],
shardArgs: ['--ansi', '--color'],
token: 'tu-token-va-aquí',
});
2
3
4
5
La propiedad execArgv
es la que normalmente pasarías a Node sin sharding, p.ej:
node --trace-warnings bot.js
Puede encontrar una lista de opciones de línea de comandos para Node aquíopen in new window.
La propiedad shardArgs
es lo que normalmente pasarías a tu bot sin sharding, por ejemplo:
node bot.js --ansi --color
Puede acceder a ellos más tarde como de costumbre a través de process.argv
, que contiene un array de ejecutables, su archivo principal, y los argumentos de línea de comandos utilizados para ejecutar el script.
Argumentos para evaluación
Puede llegar un momento en el que quieras pasar argumentos del ámbito externo a una llamada .broadcastEval()
.
function funcName(c, { arg }) {
// ...
}
client.shard.broadcastEval(funcName, { context: { arg: 'arg' } });
2
3
4
5
El BroadcastEvalOptions
open in new window typedef se introdujo en discord.js v13 como segundo parámetro en .broadcastEval()
. Acepta dos propiedades: shard
y context
. La propiedad context
se enviará como segundo argumento a su función.
En este pequeño fragmento, se pasa un argumento a la función funcName
a través de este parámetro. La función recibirá los argumentos como un objeto como segundo parámetro.
ADVERTENCIA
La opción context
sólo acepta propiedades que sean serializables en JSON. Esto significa que no puedes pasar tipos de datos complejos en el contexto directamente. Por ejemplo, si enviara una instancia de Usuario
, la función recibiría el objeto de datos sin procesar.