async execute(payload) { debug('Execute worker'); try { await this.worker(payload); } catch (error) { this.logger.error(error); } finally { this.pop(); } }
killNode(node) { this.logger.info(`Killing ${node.nodeID} node...`); node.worker.kill("SIGTERM"); }
async start() { const modelGraph = ( await tf.node.getMetaGraphsFromSavedModel(this.settings.path) )[0]; this.params = Runtime.computeParams(this.settings, modelGraph); await this.worker.loadModel(this.params); }
// Expose some worker-specific metric as an example setInterval(() => { c.inc({ code: `worker_${cluster.worker.id}` }); }, 2000);
describe("Worker Not Supported", function(){ it("Should not support worker", function(){ if(typeof Worker !== "undefined"){ Worker = void 0; } flexsearch_worker = new FlexSearch({ encode: false, async: false, worker: 4 }); if((env !== "min") && (env !== "pre")){ expect(flexsearch_worker.info().worker).to.equal(false); } }); });
/** * Immediately kills the shard's process/worker and does not restart it. */ kill() { if (this.process) { this.process.removeListener('exit', this._exitListener); this.process.kill(); } else { this.worker.removeListener('exit', this._exitListener); this.worker.terminate(); } this._handleExit(false); }
it("Should load balance requests to available nodes.", () => { // Ensure that messages are evenly distributed return Promise.all(Array(12).fill().map(callShortDelay)) .catch(protectReject).then(res => { expect(res).toHaveLength(12); expect(res).toEqual(expect.arrayContaining([ expect.objectContaining({ worker: 1 }), expect.objectContaining({ worker: 2 }), expect.objectContaining({ worker: 3 }), ])); expect(res.map(n => n.worker).sort()).toEqual([ 1,1,1,1, 2,2,2,2, 3,3,3,3 ]); }); });
startNewNode(nodeID) { this.logger.info(`Starting ${nodeID} node...`); const worker = cluster.fork(); worker.nodeID = nodeID; worker.on("message", msg => this.workerMessageHandler(worker, msg)); worker.on("disconnect", () => { const idx = this.nodes.findIndex(node => node.worker == worker); if (idx != -1) { const node = this.nodes[idx]; this.nodes.splice(idx, 1); this.logger.info(`Node ${node.nodeID} stopped.`); this.removeNodeIDFromMetric(node.nodeID); } }); worker.send({ cmd: "start", nodeID }); this.nodes.push({ nodeID, worker }); }
async runInference(ids, attentionMask, tokenTypeIds) { const result = this.worker.queueInference( this.params.path, ids, attentionMask, tokenTypeIds ); return result; }
/** * Sends a message to the shard's process/worker. * @param {*} message Message to send to the shard * @returns {Promise<Shard>} */ send(message) { return new Promise((resolve, reject) => { if (this.process) { this.process.send(message, err => { if (err) reject(err); else resolve(this); }); } else { this.worker.postMessage(message); resolve(this); } }); }
/** * Handles the shard's process/worker exiting. * @param {boolean} [respawn=this.manager.respawn] Whether to spawn the shard again * @private */ _handleExit(respawn = this.manager.respawn) { /** * Emitted upon the shard's child process/worker exiting. * @event Shard#death * @param {ChildProcess|Worker} process Child process/worker that exited */ this.emit('death', this.process || this.worker); this.ready = false; this.process = null; this.worker = null; this._evals.clear(); this._fetches.clear(); if (respawn) this.spawn().catch(err => this.emit('error', err)); }
stop() { this.worker.close(); }
stopNode(node) { this.logger.info(`Stopping ${node.nodeID} node...`); node.worker.send({ cmd: "stop" }); }
async execute(payload) { debug('Execute worker'); try { await this.worker(payload); } catch (error) { this.logger.error(error); } finally { this.pop(); } }
it("Should load balance requests to available nodes.", () => { // Ensure that messages are evenly distributed return Promise.all( Array(12) .fill() .map(callShortDelay) ) .catch(protectReject) .then(res => { expect(res).toHaveLength(12); expect(res).toEqual( expect.arrayContaining([ expect.objectContaining({ worker: 1 }), expect.objectContaining({ worker: 2 }), expect.objectContaining({ worker: 3 }) ]) ); expect(res.map(n => n.worker).sort()).toEqual([1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]); }); });