UNPKG

node-worker-threads-pool-ts

Version:

Simple worker threads pool using Node's worker_threads module. Compatible with ES6+ Promise, Typescript, Async/Await.

103 lines 3.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Pool = void 0; const events_1 = require("events"); const task_container_1 = require("./task-container"); const promise_with_timer_1 = require("./promise-with-timer"); class Pool extends events_1.EventEmitter { constructor(size) { super(); this._deprecated = false; this._workers = []; this._createWorker = null; this._taskQueue = []; if (typeof size !== "number") { throw new TypeError('"size" must be the type of number!'); } if (Number.isNaN(size)) { throw new Error('"size" must not be NaN!'); } if (size < 1) { throw new RangeError('"size" must not be lower than 1!'); } this._size = size; this._addEventHandlers(); } _addEventHandlers() { this.on("worker-ready", (worker) => { this._processTask(worker); }); } _addWorkerLifecycleHandlers(worker) { worker.on("ready", (worker) => this.emit("worker-ready", worker)); worker.once("exit", (code) => { if (this._deprecated || code === 0) { return; } this._replaceWorker(worker); }); } _setWorkerCreator(getWorker) { this._createWorker = () => { const worker = getWorker(); this._addWorkerLifecycleHandlers(worker); return worker; }; } _replaceWorker(worker) { const i = this._workers.indexOf(worker); this._workers[i] = this._createWorker(); } _getIdleWorker() { const worker = this._workers.find((worker) => worker.ready); return worker ? worker : null; } _processTask(worker) { const task = this._taskQueue.shift(); if (!task) { return; } const { param, resolve, reject, taskConfig } = task; worker .run(param, taskConfig) .then(resolve) .catch((error) => { if (promise_with_timer_1.isTimeoutError(error)) { worker.terminate(); } reject(error); }); } fill(getWorker) { this._setWorkerCreator(getWorker); const size = this._size; for (let i = 0; i < size; i++) { this._workers.push(this._createWorker()); } } runTask(param, taskConfig) { if (this._deprecated) { throw new Error("This pool is deprecated! Please use a new one."); } return new Promise((resolve, reject) => { const task = new task_container_1.TaskContainer(param, resolve, reject, taskConfig); this._taskQueue.push(task); const worker = this._getIdleWorker(); if (worker) { this._processTask(worker); } }); } /** * Destroy this pool and terminate all threads. */ async destroy() { this._deprecated = true; this.removeAllListeners(); const workers = this._workers; this._workers = []; await Promise.all(workers.map((worker) => worker.terminate())); } } exports.Pool = Pool; //# sourceMappingURL=pool.js.map