mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
Add shard client prop fetching, remove guild count fetching, improve eval
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -150,6 +150,11 @@ class Client extends EventEmitter {
|
||||
} catch (err) {
|
||||
process.send({ _evalError: err });
|
||||
}
|
||||
} else if (message._fetchProp) {
|
||||
const props = message._fetchProp.split('.');
|
||||
let value = this; // eslint-disable-line consistent-this
|
||||
for (const prop of props) value = value[prop];
|
||||
process.send({ _fetchProp: message._fetchProp, _fetchPropValue: value });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -39,6 +39,9 @@ class Shard {
|
||||
this.process.once('exit', () => {
|
||||
if (this.manager.respawn) this.manager.createShard(this.id);
|
||||
});
|
||||
|
||||
this._evals = new Set();
|
||||
this._fetches = new Set();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,14 +61,18 @@ class Shard {
|
||||
/**
|
||||
* Evaluates a script on the shard, in the context of the Client.
|
||||
* @param {string} script JavaScript to run on the shard
|
||||
* @returns {Promise<*>} Result of the script
|
||||
* @returns {Promise<*>} Result of the script execution
|
||||
*/
|
||||
eval(script) {
|
||||
if (this._evals.has(script)) return Promise.reject(new Error('Already running an eval for the script.'));
|
||||
this._evals.add(script);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const listener = message => {
|
||||
if (!message) return;
|
||||
if (message._evalResult) {
|
||||
this.process.removeListener('message', listener);
|
||||
this._evals.delete(script);
|
||||
resolve(message._evalResult);
|
||||
} else if (message._evalError) {
|
||||
this.process.removeListener('message', listener);
|
||||
@@ -73,6 +80,7 @@ class Shard {
|
||||
err.name = message._evalError.name;
|
||||
err.columnNumber = message._evalError.columnNumber;
|
||||
err.stack = message._evalError.stack;
|
||||
this._evals.delete(script);
|
||||
reject(err);
|
||||
}
|
||||
};
|
||||
@@ -80,6 +88,37 @@ class Shard {
|
||||
|
||||
this.send({ _eval: script }).catch(err => {
|
||||
this.process.removeListener('message', listener);
|
||||
this._evals.delete(script);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a Client property value of the shard.
|
||||
* @param {string} prop Name of the Client property to get, using periods for nesting
|
||||
* @returns {Promise<*>}
|
||||
* @example
|
||||
* shard.fetchClientValue('guilds.size').then(count => {
|
||||
* console.log(`${count} guilds in shard ${shard.id}`);
|
||||
* }).catch(console.error);
|
||||
*/
|
||||
fetchClientValue(prop) {
|
||||
if (this._fetches.has(prop)) return Promise.reject(new Error(`Already running a fetch for ${prop}.`));
|
||||
this._fetches.add(prop);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const listener = message => {
|
||||
if (typeof message !== 'object' || message._fetchProp !== prop) return;
|
||||
this.process.removeListener('message', listener);
|
||||
this._fetches.delete(prop);
|
||||
resolve(message._fetchPropValue);
|
||||
};
|
||||
this.process.on('message', listener);
|
||||
|
||||
this.send({ _fetchProp: prop }).catch(err => {
|
||||
this.process.removeListener('message', listener);
|
||||
this._fetches.delete(prop);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -117,7 +117,7 @@ class ShardingManager extends EventEmitter {
|
||||
/**
|
||||
* Evaluates a script on all shards, in the context of the Clients.
|
||||
* @param {string} script JavaScript to run on each shard
|
||||
* @returns {Promise<Array>} Results of the script
|
||||
* @returns {Promise<Array>} Results of the script execution
|
||||
*/
|
||||
broadcastEval(script) {
|
||||
const promises = [];
|
||||
@@ -126,48 +126,20 @@ class ShardingManager extends EventEmitter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the total guild count across all shards.
|
||||
* @param {number} [timeout=3000] Time to automatically fail after (in milliseconds)
|
||||
* @returns {Promise<number>}
|
||||
* Fetches a Client property value of each shard.
|
||||
* @param {string} prop Name of the Client property to get, using periods for nesting
|
||||
* @returns {Promise<Array>}
|
||||
* @example
|
||||
* manager.fetchClientValues('guilds.size').then(results => {
|
||||
* console.log(`${results.reduce((prev, val) => prev + val, 0)} total guilds`);
|
||||
* }).catch(console.error);
|
||||
*/
|
||||
fetchGuildCount(timeout = 3000) {
|
||||
fetchClientValues(prop) {
|
||||
if (this.shards.size === 0) return Promise.reject(new Error('No shards have been spawned.'));
|
||||
if (this.shards.size !== this.totalShards) return Promise.reject(new Error('Still spawning shards.'));
|
||||
if (this._guildCountPromise) return this._guildCountPromise;
|
||||
|
||||
this._guildCountPromise = new Promise((resolve, reject) => {
|
||||
this._guildCount = 0;
|
||||
this._guildCountReplies = 0;
|
||||
|
||||
const listener = message => {
|
||||
if (typeof message !== 'object' || !message._guildCount) return;
|
||||
|
||||
this._guildCountReplies++;
|
||||
this._guildCount += message._guildCount;
|
||||
|
||||
if (this._guildCountReplies >= this.shards.size) {
|
||||
clearTimeout(this._guildCountTimeout);
|
||||
process.removeListener('message', listener);
|
||||
this._guildCountTimeout = null;
|
||||
this._guildCountPromise = null;
|
||||
resolve(this._guildCount);
|
||||
}
|
||||
};
|
||||
process.on('message', listener);
|
||||
|
||||
this._guildCountTimeout = setTimeout(() => {
|
||||
process.removeListener('message', listener);
|
||||
this._guildCountPromise = null;
|
||||
reject(new Error('Took too long to fetch the guild count.'));
|
||||
}, timeout);
|
||||
|
||||
this.broadcast('_guildCount').catch(err => {
|
||||
process.removeListener('message', listener);
|
||||
this._guildCountPromise = null;
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
return this._guildCountPromise;
|
||||
const promises = [];
|
||||
for (const shard of this.shards.values()) promises.push(shard.fetchClientValue(prop));
|
||||
return Promise.all(promises);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user