fix(Shard): eval promise never resolves (#6649)

This commit is contained in:
D Trombett
2021-09-23 13:48:22 +02:00
committed by GitHub
parent ecd637f7d6
commit 5070d23914

View File

@@ -270,33 +270,35 @@ class Shard extends EventEmitter {
* @returns {Promise<*>} Result of the script execution * @returns {Promise<*>} Result of the script execution
*/ */
eval(script) { eval(script) {
// Stringify the script if it's a Function
const _eval = typeof script === 'function' ? `(${script})(this)` : script;
// Shard is dead (maybe respawning), don't cache anything and error immediately // Shard is dead (maybe respawning), don't cache anything and error immediately
if (!this.process && !this.worker) return Promise.reject(new Error('SHARDING_NO_CHILD_EXISTS', this.id)); if (!this.process && !this.worker) return Promise.reject(new Error('SHARDING_NO_CHILD_EXISTS', this.id));
// Cached promise from previous call // Cached promise from previous call
if (this._evals.has(script)) return this._evals.get(script); if (this._evals.has(_eval)) return this._evals.get(_eval);
const promise = new Promise((resolve, reject) => { const promise = new Promise((resolve, reject) => {
const child = this.process ?? this.worker; const child = this.process ?? this.worker;
const listener = message => { const listener = message => {
if (message?._eval !== script) return; if (message?._eval !== _eval) return;
child.removeListener('message', listener); child.removeListener('message', listener);
this._evals.delete(script); this._evals.delete(_eval);
if (!message._error) resolve(message._result); if (!message._error) resolve(message._result);
else reject(Util.makeError(message._error)); else reject(Util.makeError(message._error));
}; };
child.on('message', listener); child.on('message', listener);
const _eval = typeof script === 'function' ? `(${script})(this)` : script;
this.send({ _eval }).catch(err => { this.send({ _eval }).catch(err => {
child.removeListener('message', listener); child.removeListener('message', listener);
this._evals.delete(script); this._evals.delete(_eval);
reject(err); reject(err);
}); });
}); });
this._evals.set(script, promise); this._evals.set(_eval, promise);
return promise; return promise;
} }