New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

poolifier

Package Overview
Dependencies
Maintainers
1
Versions
192
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

poolifier - npm Package Compare versions

Comparing version 2.3.10 to 2.4.0-2

./lib/index.js

2

lib/index.js

@@ -1,1 +0,1 @@

"use strict";var e,r=require("cluster"),t=require("events"),s=require("os"),o=require("worker_threads"),i=require("async_hooks");!function(e){e.FIXED="fixed",e.DYNAMIC="dynamic"}(e||(e={}));const n=Object.freeze((()=>{})),a=Object.freeze({SOFT:"SOFT",HARD:"HARD"});class h extends t{}const k=Object.freeze({ROUND_ROBIN:"ROUND_ROBIN",LESS_RECENTLY_USED:"LESS_RECENTLY_USED",FAIR_SHARE:"FAIR_SHARE",WEIGHTED_ROUND_ROBIN:"WEIGHTED_ROUND_ROBIN"});class c{pool;isDynamicPool;requiredStatistics={runTime:!1};constructor(r){this.pool=r,this.isDynamicPool=this.pool.type===e.DYNAMIC}}class u extends c{requiredStatistics={runTime:!0};workerLastVirtualTaskTimestamp=new Map;reset(){return this.workerLastVirtualTaskTimestamp.clear(),!0}choose(){let e,r=1/0;for(const t of this.pool.workers){this.computeWorkerLastVirtualTaskTimestamp(t);const s=this.workerLastVirtualTaskTimestamp.get(t)?.end??0;s<r&&(r=s,e=t)}return e}computeWorkerLastVirtualTaskTimestamp(e){const r=Math.max(Date.now(),this.workerLastVirtualTaskTimestamp.get(e)?.end??-1/0);this.workerLastVirtualTaskTimestamp.set(e,{start:r,end:r+(this.pool.getWorkerAverageTasksRunTime(e)??0)})}}class l extends c{reset(){return!0}choose(){let e,r=1/0;for(const t of this.pool.workers){const s=this.pool.getWorkerRunningTasks(t);if(!this.isDynamicPool&&0===s)return t;s<r&&(e=t,r=s)}return e}}class p extends c{nextWorkerIndex=0;reset(){return this.nextWorkerIndex=0,!0}choose(){const e=this.pool.workers[this.nextWorkerIndex];return this.nextWorkerIndex=this.nextWorkerIndex===this.pool.workers.length-1?0:this.nextWorkerIndex+1,e}}class g extends c{requiredStatistics={runTime:!0};currentWorkerIndex=0;defaultWorkerWeight;workersTaskRunTime=new Map;constructor(e){super(e),this.defaultWorkerWeight=this.computeWorkerWeight(),this.initWorkersTaskRunTime()}reset(){return this.currentWorkerIndex=0,this.workersTaskRunTime.clear(),this.initWorkersTaskRunTime(),!0}choose(){const e=this.pool.workers[this.currentWorkerIndex];this.isDynamicPool&&!this.workersTaskRunTime.has(e)&&this.initWorkerTaskRunTime(e);const r=this.workersTaskRunTime.get(e)?.runTime??0,t=this.workersTaskRunTime.get(e)?.weight??this.defaultWorkerWeight;return r<t?this.setWorkerTaskRunTime(e,t,r+(this.getWorkerVirtualTaskRunTime(e)??0)):(this.currentWorkerIndex=this.currentWorkerIndex===this.pool.workers.length-1?0:this.currentWorkerIndex+1,this.setWorkerTaskRunTime(this.pool.workers[this.currentWorkerIndex],t,0)),e}initWorkersTaskRunTime(){for(const e of this.pool.workers)this.initWorkerTaskRunTime(e)}initWorkerTaskRunTime(e){this.setWorkerTaskRunTime(e,this.defaultWorkerWeight,0)}setWorkerTaskRunTime(e,r,t){this.workersTaskRunTime.set(e,{weight:r,runTime:t})}getWorkerVirtualTaskRunTime(e){return this.pool.getWorkerAverageTasksRunTime(e)}computeWorkerWeight(){let e=0;for(const r of s.cpus()){const t=r.speed.toString().length-1;e+=1/(r.speed/Math.pow(10,t))*Math.pow(10,t)}return Math.round(e/s.cpus().length)}}function m(e,r=k.ROUND_ROBIN){switch(r){case k.ROUND_ROBIN:return new p(e);case k.LESS_RECENTLY_USED:return new l(e);case k.FAIR_SHARE:return new u(e);case k.WEIGHTED_ROUND_ROBIN:return new g(e);default:throw new Error(`Worker choice strategy '${r}' not found`)}}class T extends c{createDynamicallyWorkerCallback;workerChoiceStrategy;constructor(e,r,t=k.ROUND_ROBIN){super(e),this.createDynamicallyWorkerCallback=r,this.workerChoiceStrategy=m(this.pool,t),this.requiredStatistics=this.workerChoiceStrategy.requiredStatistics}reset(){return this.workerChoiceStrategy.reset()}choose(){const e=this.pool.findFreeWorker();return!1!==e?e:this.pool.busy?this.workerChoiceStrategy.choose():this.createDynamicallyWorkerCallback()}}class W{pool;createDynamicallyWorkerCallback;workerChoiceStrategy;constructor(e,r,t=k.ROUND_ROBIN){this.pool=e,this.createDynamicallyWorkerCallback=r,this.setWorkerChoiceStrategy(t)}getPoolWorkerChoiceStrategy(r=k.ROUND_ROBIN){return this.pool.type===e.DYNAMIC?new T(this.pool,this.createDynamicallyWorkerCallback,r):m(this.pool,r)}getWorkerChoiceStrategy(){return this.workerChoiceStrategy}setWorkerChoiceStrategy(e){this.workerChoiceStrategy?.reset(),this.workerChoiceStrategy=this.getPoolWorkerChoiceStrategy(e)}execute(){return this.workerChoiceStrategy.choose()}}class w{numberOfWorkers;filePath;opts;workers=[];workersTasksUsage=new Map;emitter;promiseMap=new Map;nextMessageId=0;workerChoiceStrategyContext;constructor(e,r,t){if(this.numberOfWorkers=e,this.filePath=r,this.opts=t,!this.isMain())throw new Error("Cannot start a pool from a worker!");this.checkNumberOfWorkers(this.numberOfWorkers),this.checkFilePath(this.filePath),this.checkPoolOptions(this.opts),this.setupHook();for(let e=1;e<=this.numberOfWorkers;e++)this.createAndSetupWorker();!0===this.opts.enableEvents&&(this.emitter=new h),this.workerChoiceStrategyContext=new W(this,(()=>{const e=this.createAndSetupWorker();return this.registerWorkerMessageListener(e,(r=>{var t;t=a.HARD,(r.kill===t||0===this.getWorkerRunningTasks(e))&&this.destroyWorker(e)})),e}),this.opts.workerChoiceStrategy)}checkFilePath(e){if(null==e||0===e.length)throw new Error("Please specify a file with a worker implementation")}checkNumberOfWorkers(r){if(null==r)throw new Error("Cannot instantiate a pool without specifying the number of workers");if(!Number.isSafeInteger(r))throw new TypeError("Cannot instantiate a pool with a non integer number of workers");if(r<0)throw new RangeError("Cannot instantiate a pool with a negative number of workers");if(this.type===e.FIXED&&0===r)throw new Error("Cannot instantiate a fixed pool with no worker")}checkPoolOptions(e){this.opts.workerChoiceStrategy=e.workerChoiceStrategy??k.ROUND_ROBIN,this.opts.enableEvents=e.enableEvents??!0}get numberOfRunningTasks(){return this.promiseMap.size}getWorkerIndex(e){return this.workers.indexOf(e)}getWorkerRunningTasks(e){return this.workersTasksUsage.get(e)?.running}getWorkerAverageTasksRunTime(e){return this.workersTasksUsage.get(e)?.avgRunTime}setWorkerChoiceStrategy(e){this.opts.workerChoiceStrategy=e;for(const e of this.workers)this.resetWorkerTasksUsage(e);this.workerChoiceStrategyContext.setWorkerChoiceStrategy(e)}internalGetBusyStatus(){return this.numberOfRunningTasks>=this.numberOfWorkers&&!1===this.findFreeWorker()}findFreeWorker(){for(const e of this.workers)if(0===this.getWorkerRunningTasks(e))return e;return!1}async execute(e){const r=this.chooseWorker(),t=this.internalExecute(r,this.nextMessageId);return this.checkAndEmitBusy(),this.sendToWorker(r,{data:e??{},id:this.nextMessageId}),++this.nextMessageId,t}async destroy(){await Promise.all(this.workers.map((async e=>{await this.destroyWorker(e)})))}setupHook(){}beforePromiseWorkerResponseHook(e){this.increaseWorkerRunningTasks(e)}afterPromiseWorkerResponseHook(e,r){this.decreaseWorkerRunningTasks(r.worker),this.stepWorkerRunTasks(r.worker,1),this.updateWorkerTasksRunTime(r.worker,e.taskRunTime)}removeWorker(e){this.workers.splice(this.getWorkerIndex(e),1),this.removeWorkerTasksUsage(e)}chooseWorker(){return this.workerChoiceStrategyContext.execute()}createAndSetupWorker(){const e=this.createWorker();return e.on("message",this.opts.messageHandler??n),e.on("error",this.opts.errorHandler??n),e.on("online",this.opts.onlineHandler??n),e.on("exit",this.opts.exitHandler??n),e.once("exit",(()=>{this.removeWorker(e)})),this.workers.push(e),this.initWorkerTasksUsage(e),this.afterWorkerSetup(e),e}workerListener(){return e=>{if(void 0!==e.id){const r=this.promiseMap.get(e.id);void 0!==r&&(null!=e.error?r.reject(e.error):r.resolve(e.data),this.afterPromiseWorkerResponseHook(e,r),this.promiseMap.delete(e.id))}}}async internalExecute(e,r){return this.beforePromiseWorkerResponseHook(e),await new Promise(((t,s)=>{this.promiseMap.set(r,{resolve:t,reject:s,worker:e})}))}checkAndEmitBusy(){!0===this.opts.enableEvents&&this.busy&&this.emitter?.emit("busy")}increaseWorkerRunningTasks(e){this.stepWorkerRunningTasks(e,1)}decreaseWorkerRunningTasks(e){this.stepWorkerRunningTasks(e,-1)}stepWorkerRunningTasks(e,r){if(this.checkWorkerTasksUsage(e)){const t=this.workersTasksUsage.get(e);t.running=t.running+r,this.workersTasksUsage.set(e,t)}}stepWorkerRunTasks(e,r){if(this.checkWorkerTasksUsage(e)){const t=this.workersTasksUsage.get(e);t.run=t.run+r,this.workersTasksUsage.set(e,t)}}updateWorkerTasksRunTime(e,r){if(this.workerChoiceStrategyContext.getWorkerChoiceStrategy().requiredStatistics.runTime&&this.checkWorkerTasksUsage(e)){const t=this.workersTasksUsage.get(e);t.runTime+=r??0,0!==t.run&&(t.avgRunTime=t.runTime/t.run),this.workersTasksUsage.set(e,t)}}checkWorkerTasksUsage(e){const r=this.workersTasksUsage.has(e);if(!r)throw new Error("Worker could not be found in workers tasks usage map");return r}initWorkerTasksUsage(e){this.workersTasksUsage.set(e,{run:0,running:0,runTime:0,avgRunTime:0})}removeWorkerTasksUsage(e){this.workersTasksUsage.delete(e)}resetWorkerTasksUsage(e){this.removeWorkerTasksUsage(e),this.initWorkerTasksUsage(e)}}class d extends w{opts;constructor(e,r,t={}){super(e,r,t),this.opts=t}setupHook(){r.setupPrimary({...this.opts.settings,exec:this.filePath})}isMain(){return r.isPrimary}destroyWorker(e){this.sendToWorker(e,{kill:1}),e.kill()}sendToWorker(e,r){e.send(r)}registerWorkerMessageListener(e,r){e.on("message",r)}createWorker(){return r.fork(this.opts.env)}afterWorkerSetup(e){this.registerWorkerMessageListener(e,super.workerListener())}get type(){return e.FIXED}get busy(){return this.internalGetBusyStatus()}}class y extends w{constructor(e,r,t={}){super(e,r,t)}isMain(){return o.isMainThread}async destroyWorker(e){this.sendToWorker(e,{kill:1}),await e.terminate()}sendToWorker(e,r){e.postMessage(r)}registerWorkerMessageListener(e,r){e.port2?.on("message",r)}createWorker(){return new o.Worker(this.filePath,{env:o.SHARE_ENV})}afterWorkerSetup(e){const{port1:r,port2:t}=new o.MessageChannel;e.postMessage({parent:r},[r]),e.port1=r,e.port2=t,this.registerWorkerMessageListener(e,super.workerListener())}get type(){return e.FIXED}get busy(){return this.internalGetBusyStatus()}}const f=6e4,R=a.SOFT;class x extends i.AsyncResource{mainWorker;lastTaskTimestamp;aliveInterval;opts;constructor(e,r,t,s,o={killBehavior:R,maxInactiveTime:f}){super(e),this.mainWorker=s,this.opts=o,this.checkFunctionInput(t),this.checkWorkerOptions(this.opts),this.lastTaskTimestamp=Date.now(),r||(this.aliveInterval=setInterval(this.checkAlive.bind(this),(this.opts.maxInactiveTime??f)/2),this.checkAlive.bind(this)()),this.mainWorker?.on("message",(e=>{this.messageListener(e,t)}))}messageListener(e,r){void 0!==e.data&&void 0!==e.id?!0===this.opts.async?this.runInAsyncScope(this.runAsync.bind(this),this,r,e):this.runInAsyncScope(this.run.bind(this),this,r,e):void 0!==e.parent?this.mainWorker=e.parent:void 0!==e.kill&&(null!=this.aliveInterval&&clearInterval(this.aliveInterval),this.emitDestroy())}checkWorkerOptions(e){this.opts.killBehavior=e.killBehavior??R,this.opts.maxInactiveTime=e.maxInactiveTime??f,this.opts.async=e.async??!1}checkFunctionInput(e){if(null==e)throw new Error("fn parameter is mandatory");if("function"!=typeof e)throw new TypeError("fn parameter is not a function")}getMainWorker(){if(null==this.mainWorker)throw new Error("Main worker was not set");return this.mainWorker}checkAlive(){Date.now()-this.lastTaskTimestamp>(this.opts.maxInactiveTime??f)&&this.sendToMainWorker({kill:this.opts.killBehavior})}handleError(e){return e}run(e,r){try{const t=Date.now(),s=e(r.data),o=Date.now()-t;this.sendToMainWorker({data:s,id:r.id,taskRunTime:o})}catch(e){const t=this.handleError(e);this.sendToMainWorker({error:t,id:r.id})}finally{this.lastTaskTimestamp=Date.now()}}runAsync(e,r){const t=Date.now();e(r.data).then((e=>{const s=Date.now()-t;return this.sendToMainWorker({data:e,id:r.id,taskRunTime:s}),null})).catch((e=>{const t=this.handleError(e);this.sendToMainWorker({error:t,id:r.id})})).finally((()=>{this.lastTaskTimestamp=Date.now()})).catch(n)}}exports.ClusterWorker=class extends x{constructor(e,t={}){super("worker-cluster-pool:poolifier",r.isPrimary,e,r.worker,t)}sendToMainWorker(e){this.getMainWorker().send(e)}handleError(e){return e instanceof Error?e.message:e}},exports.DynamicClusterPool=class extends d{max;constructor(e,r,t,s={}){super(e,t,s),this.max=r}get type(){return e.DYNAMIC}get busy(){return this.workers.length===this.max}},exports.DynamicThreadPool=class extends y{max;constructor(e,r,t,s={}){super(e,t,s),this.max=r}get type(){return e.DYNAMIC}get busy(){return this.workers.length===this.max}},exports.FixedClusterPool=d,exports.FixedThreadPool=y,exports.KillBehaviors=a,exports.ThreadWorker=class extends x{constructor(e,r={}){super("worker-thread-pool:poolifier",o.isMainThread,e,o.parentPort,r)}sendToMainWorker(e){this.getMainWorker().postMessage(e)}},exports.WorkerChoiceStrategies=k;
"use strict";var e,r=require("node:cluster"),t=require("node:crypto"),s=require("node:events"),o=require("node:os"),i=require("node:worker_threads"),n=require("node:async_hooks");!function(e){e.FIXED="fixed",e.DYNAMIC="dynamic"}(e||(e={}));const a=Object.freeze((()=>{})),h=Object.freeze({SOFT:"SOFT",HARD:"HARD"});function k(e,r){return r===e}class u extends s{}const c=Object.freeze({ROUND_ROBIN:"ROUND_ROBIN",LESS_USED:"LESS_USED",LESS_BUSY:"LESS_BUSY",FAIR_SHARE:"FAIR_SHARE",WEIGHTED_ROUND_ROBIN:"WEIGHTED_ROUND_ROBIN"});class l{pool;isDynamicPool;requiredStatistics={runTime:!1};constructor(r){this.pool=r,this.isDynamicPool=this.pool.type===e.DYNAMIC}}class p extends l{requiredStatistics={runTime:!0};workerLastVirtualTaskTimestamp=new Map;reset(){return this.workerLastVirtualTaskTimestamp.clear(),!0}choose(){let e,r=1/0;for(const[t]of this.pool.workers.entries()){this.computeWorkerLastVirtualTaskTimestamp(t);const s=this.workerLastVirtualTaskTimestamp.get(t)?.end??0;s<r&&(r=s,e=t)}return e}remove(e){const r=this.workerLastVirtualTaskTimestamp.delete(e);for(const[r,t]of this.workerLastVirtualTaskTimestamp.entries())r>e&&this.workerLastVirtualTaskTimestamp.set(r-1,t);return r}computeWorkerLastVirtualTaskTimestamp(e){const r=Math.max(Date.now(),this.workerLastVirtualTaskTimestamp.get(e)?.end??-1/0);this.workerLastVirtualTaskTimestamp.set(e,{start:r,end:r+(this.pool.workers[e].tasksUsage.avgRunTime??0)})}}class m extends l{requiredStatistics={runTime:!0};reset(){return!0}choose(){let e,r=1/0;for(const[t,s]of this.pool.workers.entries()){const o=s.tasksUsage.runTime;if(!this.isDynamicPool&&0===o)return t;o<r&&(r=o,e=t)}return e}remove(e){return!0}}class d extends l{reset(){return!0}choose(){let e,r=1/0;for(const[t,s]of this.pool.workers.entries()){const o=s.tasksUsage,i=o?.run+o?.running;if(!this.isDynamicPool&&0===i)return t;i<r&&(r=i,e=t)}return e}remove(e){return!0}}class w extends l{nextWorkerId=0;reset(){return this.nextWorkerId=0,!0}choose(){const e=this.nextWorkerId;return this.nextWorkerId=this.nextWorkerId===this.pool.workers.length-1?0:this.nextWorkerId+1,e}remove(e){return this.nextWorkerId===e&&(this.nextWorkerId=this.nextWorkerId>this.pool.workers.length-1?this.pool.workers.length-1:this.nextWorkerId),!0}}class g extends l{requiredStatistics={runTime:!0};currentWorkerId=0;defaultWorkerWeight;workersTaskRunTime=new Map;constructor(e){super(e),this.defaultWorkerWeight=this.computeWorkerWeight(),this.initWorkersTaskRunTime()}reset(){return this.currentWorkerId=0,this.workersTaskRunTime.clear(),this.initWorkersTaskRunTime(),!0}choose(){const e=this.currentWorkerId;this.isDynamicPool&&!this.workersTaskRunTime.has(e)&&this.initWorkerTaskRunTime(e);const r=this.workersTaskRunTime.get(e)?.runTime??0,t=this.workersTaskRunTime.get(e)?.weight??this.defaultWorkerWeight;return r<t?this.setWorkerTaskRunTime(e,t,r+(this.getWorkerVirtualTaskRunTime(e)??0)):(this.currentWorkerId=this.currentWorkerId===this.pool.workers.length-1?0:this.currentWorkerId+1,this.setWorkerTaskRunTime(this.currentWorkerId,t,0)),e}remove(e){this.currentWorkerId===e&&(this.currentWorkerId=this.currentWorkerId>this.pool.workers.length-1?this.pool.workers.length-1:this.currentWorkerId);const r=this.workersTaskRunTime.delete(e);for(const[r,t]of this.workersTaskRunTime)r>e&&this.workersTaskRunTime.set(r-1,t);return r}initWorkersTaskRunTime(){for(const[e]of this.pool.workers.entries())this.initWorkerTaskRunTime(e)}initWorkerTaskRunTime(e){this.setWorkerTaskRunTime(e,this.defaultWorkerWeight,0)}setWorkerTaskRunTime(e,r,t){this.workersTaskRunTime.set(e,{weight:r,runTime:t})}getWorkerVirtualTaskRunTime(e){return this.pool.workers[e].tasksUsage.avgRunTime}computeWorkerWeight(){let e=0;for(const r of o.cpus()){const t=r.speed.toString().length-1;e+=1/(r.speed/Math.pow(10,t))*Math.pow(10,t)}return Math.round(e/o.cpus().length)}}function W(e,r=c.ROUND_ROBIN){switch(r){case c.ROUND_ROBIN:return new w(e);case c.LESS_USED:return new d(e);case c.LESS_BUSY:return new m(e);case c.FAIR_SHARE:return new p(e);case c.WEIGHTED_ROUND_ROBIN:return new g(e);default:throw new Error(`Worker choice strategy '${r}' not found`)}}class T extends l{createWorkerCallback;workerChoiceStrategy;constructor(e,r,t=c.ROUND_ROBIN){super(e),this.createWorkerCallback=r,this.workerChoiceStrategy=W(this.pool,t),this.requiredStatistics=this.workerChoiceStrategy.requiredStatistics}reset(){return this.workerChoiceStrategy.reset()}choose(){const e=this.pool.findFreeWorkerKey();return!1!==e?e:this.pool.busy?this.workerChoiceStrategy.choose():this.createWorkerCallback()}remove(e){return this.workerChoiceStrategy.remove(e)}}class y{pool;createWorkerCallback;workerChoiceStrategy;constructor(e,r,t=c.ROUND_ROBIN){this.pool=e,this.createWorkerCallback=r,this.setWorkerChoiceStrategy(t)}getPoolWorkerChoiceStrategy(r=c.ROUND_ROBIN){return this.pool.type===e.DYNAMIC?new T(this.pool,this.createWorkerCallback,r):W(this.pool,r)}getWorkerChoiceStrategy(){return this.workerChoiceStrategy}getRequiredStatistics(){return this.workerChoiceStrategy.requiredStatistics}setWorkerChoiceStrategy(e){this.workerChoiceStrategy?.reset(),this.workerChoiceStrategy=this.getPoolWorkerChoiceStrategy(e)}execute(){return this.workerChoiceStrategy.choose()}remove(e){return this.workerChoiceStrategy.remove(e)}}class f{numberOfWorkers;filePath;opts;workers=[];emitter;promiseResponseMap=new Map;workerChoiceStrategyContext;constructor(e,r,t){if(this.numberOfWorkers=e,this.filePath=r,this.opts=t,!this.isMain())throw new Error("Cannot start a pool from a worker!");this.checkNumberOfWorkers(this.numberOfWorkers),this.checkFilePath(this.filePath),this.checkPoolOptions(this.opts),this.setupHook();for(let e=1;e<=this.numberOfWorkers;e++)this.createAndSetupWorker();!0===this.opts.enableEvents&&(this.emitter=new u),this.workerChoiceStrategyContext=new y(this,(()=>{const e=this.createAndSetupWorker();return this.registerWorkerMessageListener(e,(r=>{(k(h.HARD,r.kill)||0===this.getWorkerTasksUsage(e)?.running)&&this.destroyWorker(e)})),this.getWorkerKey(e)}),this.opts.workerChoiceStrategy)}checkFilePath(e){if(null==e||"string"==typeof e&&0===e.trim().length)throw new Error("Please specify a file with a worker implementation")}checkNumberOfWorkers(r){if(null==r)throw new Error("Cannot instantiate a pool without specifying the number of workers");if(!Number.isSafeInteger(r))throw new TypeError("Cannot instantiate a pool with a non integer number of workers");if(r<0)throw new RangeError("Cannot instantiate a pool with a negative number of workers");if(this.type===e.FIXED&&0===r)throw new Error("Cannot instantiate a fixed pool with no worker")}checkPoolOptions(e){this.opts.workerChoiceStrategy=e.workerChoiceStrategy??c.ROUND_ROBIN,this.opts.enableEvents=e.enableEvents??!0}get numberOfRunningTasks(){return this.promiseResponseMap.size}getWorkerKey(e){return this.workers.findIndex((r=>r.worker===e))}setWorkerChoiceStrategy(e){this.opts.workerChoiceStrategy=e;for(const[e,r]of this.workers.entries())this.setWorker(e,r.worker,{run:0,running:0,runTime:0,avgRunTime:0,error:0});this.workerChoiceStrategyContext.setWorkerChoiceStrategy(e)}internalGetBusyStatus(){return this.numberOfRunningTasks>=this.numberOfWorkers&&!1===this.findFreeWorkerKey()}findFreeWorkerKey(){const e=this.workers.findIndex((e=>0===e.tasksUsage.running));return-1!==e&&e}async execute(e){const[r,s]=this.chooseWorker(),o=t.randomUUID(),i=this.internalExecute(r,s,o);return this.checkAndEmitBusy(),this.sendToWorker(s,{data:e??{},id:o}),i}async destroy(){await Promise.all(this.workers.map((async e=>{await this.destroyWorker(e.worker)})))}setupHook(){}beforePromiseResponseHook(e){++this.workers[e].tasksUsage.running}afterPromiseResponseHook(e,r){const t=this.getWorkerTasksUsage(e);--t.running,++t.run,null!=r.error&&++t.error,this.workerChoiceStrategyContext.getRequiredStatistics().runTime&&(t.runTime+=r.taskRunTime??0,0!==t.run&&(t.avgRunTime=t.runTime/t.run))}removeWorker(e){const r=this.getWorkerKey(e);this.workers.splice(r,1),this.workerChoiceStrategyContext.remove(r)}chooseWorker(){const e=this.workerChoiceStrategyContext.execute();return[e,this.workers[e].worker]}createAndSetupWorker(){const e=this.createWorker();return e.on("message",this.opts.messageHandler??a),e.on("error",this.opts.errorHandler??a),e.on("online",this.opts.onlineHandler??a),e.on("exit",this.opts.exitHandler??a),e.once("exit",(()=>{this.removeWorker(e)})),this.pushWorker(e,{run:0,running:0,runTime:0,avgRunTime:0,error:0}),this.afterWorkerSetup(e),e}workerListener(){return e=>{if(void 0!==e.id){const r=this.promiseResponseMap.get(e.id);void 0!==r&&(null!=e.error?r.reject(e.error):r.resolve(e.data),this.afterPromiseResponseHook(r.worker,e),this.promiseResponseMap.delete(e.id))}}}async internalExecute(e,r,t){return this.beforePromiseResponseHook(e),await new Promise(((e,s)=>{this.promiseResponseMap.set(t,{resolve:e,reject:s,worker:r})}))}checkAndEmitBusy(){!0===this.opts.enableEvents&&this.busy&&this.emitter?.emit("busy")}getWorkerTasksUsage(e){const r=this.getWorkerKey(e);if(-1!==r)return this.workers[r].tasksUsage;throw new Error("Worker could not be found in the pool")}pushWorker(e,r){this.workers.push({worker:e,tasksUsage:r})}setWorker(e,r,t){this.workers[e]={worker:r,tasksUsage:t}}}class R extends f{opts;constructor(e,r,t={}){super(e,r,t),this.opts=t}setupHook(){r.setupPrimary({...this.opts.settings,exec:this.filePath})}isMain(){return r.isPrimary}destroyWorker(e){this.sendToWorker(e,{kill:1}),e.kill()}sendToWorker(e,r){e.send(r)}registerWorkerMessageListener(e,r){e.on("message",r)}createWorker(){return r.fork(this.opts.env)}afterWorkerSetup(e){this.registerWorkerMessageListener(e,super.workerListener())}get type(){return e.FIXED}get busy(){return this.internalGetBusyStatus()}}class S extends f{constructor(e,r,t={}){super(e,r,t)}isMain(){return i.isMainThread}async destroyWorker(e){this.sendToWorker(e,{kill:1}),await e.terminate()}sendToWorker(e,r){e.postMessage(r)}registerWorkerMessageListener(e,r){e.port2?.on("message",r)}createWorker(){return new i.Worker(this.filePath,{env:i.SHARE_ENV})}afterWorkerSetup(e){const{port1:r,port2:t}=new i.MessageChannel;e.postMessage({parent:r},[r]),e.port1=r,e.port2=t,this.registerWorkerMessageListener(e,super.workerListener())}get type(){return e.FIXED}get busy(){return this.internalGetBusyStatus()}}const I=6e4,x=h.SOFT;class v extends n.AsyncResource{mainWorker;lastTaskTimestamp;aliveInterval;opts;constructor(e,r,t,s,o={killBehavior:x,maxInactiveTime:I}){super(e),this.mainWorker=s,this.opts=o,this.checkFunctionInput(t),this.checkWorkerOptions(this.opts),!r&&k(h.HARD,this.opts.killBehavior)&&(this.lastTaskTimestamp=Date.now(),this.aliveInterval=setInterval(this.checkAlive.bind(this),(this.opts.maxInactiveTime??I)/2),this.checkAlive.bind(this)()),this.mainWorker?.on("message",(e=>{this.messageListener(e,t)}))}messageListener(e,r){void 0!==e.data&&void 0!==e.id?!0===this.opts.async?this.runInAsyncScope(this.runAsync.bind(this),this,r,e):this.runInAsyncScope(this.run.bind(this),this,r,e):void 0!==e.parent?this.mainWorker=e.parent:void 0!==e.kill&&(null!=this.aliveInterval&&clearInterval(this.aliveInterval),this.emitDestroy())}checkWorkerOptions(e){this.opts.killBehavior=e.killBehavior??x,this.opts.maxInactiveTime=e.maxInactiveTime??I,this.opts.async=e.async??!1}checkFunctionInput(e){if(null==e)throw new Error("fn parameter is mandatory");if("function"!=typeof e)throw new TypeError("fn parameter is not a function")}getMainWorker(){if(null==this.mainWorker)throw new Error("Main worker was not set");return this.mainWorker}checkAlive(){Date.now()-this.lastTaskTimestamp>(this.opts.maxInactiveTime??I)&&this.sendToMainWorker({kill:this.opts.killBehavior})}handleError(e){return e}run(e,r){try{const t=Date.now(),s=e(r.data),o=Date.now()-t;this.sendToMainWorker({data:s,id:r.id,taskRunTime:o})}catch(e){const t=this.handleError(e);this.sendToMainWorker({error:t,id:r.id})}finally{k(h.HARD,this.opts.killBehavior)&&(this.lastTaskTimestamp=Date.now())}}runAsync(e,r){const t=Date.now();e(r.data).then((e=>{const s=Date.now()-t;return this.sendToMainWorker({data:e,id:r.id,taskRunTime:s}),null})).catch((e=>{const t=this.handleError(e);this.sendToMainWorker({error:t,id:r.id})})).finally((()=>{k(h.HARD,this.opts.killBehavior)&&(this.lastTaskTimestamp=Date.now())})).catch(a)}}exports.ClusterWorker=class extends v{constructor(e,t={}){super("worker-cluster-pool:poolifier",r.isPrimary,e,r.worker,t)}sendToMainWorker(e){this.getMainWorker().send(e)}handleError(e){return e instanceof Error?e.message:e}},exports.DynamicClusterPool=class extends R{max;constructor(e,r,t,s={}){super(e,t,s),this.max=r}get type(){return e.DYNAMIC}get busy(){return this.workers.length===this.max}},exports.DynamicThreadPool=class extends S{max;constructor(e,r,t,s={}){super(e,t,s),this.max=r}get type(){return e.DYNAMIC}get busy(){return this.workers.length===this.max}},exports.FixedClusterPool=R,exports.FixedThreadPool=S,exports.KillBehaviors=h,exports.ThreadWorker=class extends v{constructor(e,r={}){super("worker-thread-pool:poolifier",i.isMainThread,e,i.parentPort,r)}sendToMainWorker(e){this.getMainWorker().postMessage(e)}},exports.WorkerChoiceStrategies=c;

@@ -1,5 +0,5 @@

import type { MessageValue, PromiseWorkerResponseWrapper } from '../utility-types';
import type { MessageValue, PromiseResponseWrapper } from '../utility-types';
import type { PoolOptions } from './pool';
import { PoolEmitter } from './pool';
import type { IPoolInternal, TasksUsage } from './pool-internal';
import type { IPoolInternal, WorkerType } from './pool-internal';
import { PoolType } from './pool-internal';

@@ -21,21 +21,15 @@ import type { IPoolWorker } from './pool-worker';

/** {@inheritDoc} */
readonly workers: Worker[];
readonly workers: Array<WorkerType<Worker>>;
/** {@inheritDoc} */
readonly workersTasksUsage: Map<Worker, TasksUsage>;
/** {@inheritDoc} */
readonly emitter?: PoolEmitter;
/**
* The promise map.
* The promise response map.
*
* - `key`: This is the message Id of each submitted task.
* - `value`: An object that contains the worker, the resolve function and the reject function.
* - `key`: The message id of each submitted task.
* - `value`: An object that contains the worker, the promise resolve and reject callbacks.
*
* When we receive a message from the worker we get a map entry and resolve/reject the promise based on the message.
* When we receive a message from the worker we get a map entry with the promise resolve/reject bound to the message.
*/
protected promiseMap: Map<number, PromiseWorkerResponseWrapper<Worker, Response>>;
protected promiseResponseMap: Map<string, PromiseResponseWrapper<Worker, Response>>;
/**
* Id of the next message.
*/
protected nextMessageId: number;
/**
* Worker choice strategy instance implementing the worker choice algorithm.

@@ -61,9 +55,10 @@ *

get numberOfRunningTasks(): number;
/**
* Gets the given worker key.
*
* @param worker - The worker.
* @returns The worker key.
*/
private getWorkerKey;
/** {@inheritDoc} */
getWorkerIndex(worker: Worker): number;
/** {@inheritDoc} */
getWorkerRunningTasks(worker: Worker): number | undefined;
/** {@inheritDoc} */
getWorkerAverageTasksRunTime(worker: Worker): number | undefined;
/** {@inheritDoc} */
setWorkerChoiceStrategy(workerChoiceStrategy: WorkerChoiceStrategy): void;

@@ -74,3 +69,3 @@ /** {@inheritDoc} */

/** {@inheritDoc} */
findFreeWorker(): Worker | false;
findFreeWorkerKey(): number | false;
/** {@inheritDoc} */

@@ -99,5 +94,5 @@ execute(data: Data): Promise<Response>;

*
* @param worker - The worker.
* @param workerKey - The worker key.
*/
protected beforePromiseWorkerResponseHook(worker: Worker): void;
protected beforePromiseResponseHook(workerKey: number): void;
/**

@@ -107,6 +102,6 @@ * Hook executed after the worker task promise resolution.

*
* @param worker - The worker.
* @param message - The received message.
* @param promise - The Promise response.
*/
protected afterPromiseWorkerResponseHook(message: MessageValue<Response>, promise: PromiseWorkerResponseWrapper<Worker, Response>): void;
protected afterPromiseResponseHook(worker: Worker, message: MessageValue<Response>): void;
/**

@@ -123,5 +118,5 @@ * Removes the given worker from the pool.

*
* @returns Worker.
* @returns [worker key, worker].
*/
protected chooseWorker(): Worker;
protected chooseWorker(): [number, Worker];
/**

@@ -168,59 +163,23 @@ * Sends a message to the given worker.

/**
* Increases the number of tasks that the given worker has applied.
* Gets worker tasks usage.
*
* @param worker - Worker which running tasks is increased.
*/
private increaseWorkerRunningTasks;
/**
* Decreases the number of tasks that the given worker has applied.
*
* @param worker - Worker which running tasks is decreased.
*/
private decreaseWorkerRunningTasks;
/**
* Steps the number of tasks that the given worker has applied.
*
* @param worker - Worker which running tasks are stepped.
* @param step - Number of running tasks step.
*/
private stepWorkerRunningTasks;
/**
* Steps the number of tasks that the given worker has run.
*
* @param worker - Worker which has run tasks.
* @param step - Number of run tasks step.
*/
private stepWorkerRunTasks;
/**
* Updates tasks runtime for the given worker.
*
* @param worker - Worker which run the task.
* @param taskRunTime - Worker task runtime.
*/
private updateWorkerTasksRunTime;
/**
* Checks if the given worker is registered in the workers tasks usage map.
*
* @param worker - Worker to check.
* @returns `true` if the worker is registered in the workers tasks usage map. `false` otherwise.
*/
private checkWorkerTasksUsage;
/**
* Initializes tasks usage statistics.
*
* @param worker - The worker.
* @returns The worker tasks usage.
*/
private initWorkerTasksUsage;
private getWorkerTasksUsage;
/**
* Removes worker tasks usage statistics.
* Pushes the given worker.
*
* @param worker - The worker.
* @param tasksUsage - The worker tasks usage.
*/
private removeWorkerTasksUsage;
private pushWorker;
/**
* Resets worker tasks usage statistics.
* Sets the given worker.
*
* @param workerKey - The worker key.
* @param worker - The worker.
* @param tasksUsage - The worker tasks usage.
*/
private resetWorkerTasksUsage;
private setWorker;
}
/// <reference types="node" />
import type { ClusterSettings, Worker } from 'cluster';
import type { ClusterSettings, Worker } from 'node:cluster';
import type { MessageValue } from '../../utility-types';

@@ -4,0 +4,0 @@ import { AbstractPool } from '../abstract-pool';

@@ -18,4 +18,14 @@ import type { IPool } from './pool';

avgRunTime: number;
error: number;
}
/**
* Internal worker type.
*
* @typeParam Worker - Type of worker which manages this pool.
*/
export interface WorkerType<Worker extends IPoolWorker> {
worker: Worker;
tasksUsage: TasksUsage;
}
/**
* Internal contract definition for a poolifier pool.

@@ -29,13 +39,6 @@ *

/**
* List of currently available workers.
* Pool workers item array.
*/
readonly workers: Worker[];
readonly workers: Array<WorkerType<Worker>>;
/**
* The workers tasks usage map.
*
* `key`: The `Worker`
* `value`: Worker tasks usage statistics.
*/
readonly workersTasksUsage: Map<Worker, TasksUsage>;
/**
* Pool type.

@@ -57,32 +60,11 @@ *

/**
* Finds a free worker based on the number of tasks the worker has applied.
* Finds a free worker key based on the number of tasks the worker has applied.
*
* If a worker is found with `0` running tasks, it is detected as free and returned.
* If a worker is found with `0` running tasks, it is detected as free and its key is returned.
*
* If no free worker is found, `false` is returned.
*
* @returns A free worker if there is one, otherwise `false`.
* @returns A worker key if there is one, otherwise `false`.
*/
findFreeWorker: () => Worker | false;
/**
* Gets worker index.
*
* @param worker - The worker.
* @returns The worker index.
*/
getWorkerIndex: (worker: Worker) => number;
/**
* Gets worker running tasks.
*
* @param worker - The worker.
* @returns The number of tasks currently running on the worker.
*/
getWorkerRunningTasks: (worker: Worker) => number | undefined;
/**
* Gets worker average tasks runtime.
*
* @param worker - The worker.
* @returns The average tasks runtime on the worker.
*/
getWorkerAverageTasksRunTime: (worker: Worker) => number | undefined;
findFreeWorkerKey: () => number | false;
}
/// <reference types="node" />
import EventEmitter from 'events';
import EventEmitter from 'node:events';
import type { ErrorHandler, ExitHandler, MessageHandler, OnlineHandler } from './pool-worker';

@@ -4,0 +4,0 @@ import type { WorkerChoiceStrategy } from './selection-strategies/selection-strategies-types';

@@ -11,3 +11,3 @@ import type { IPoolInternal } from '../pool-internal';

*/
export declare abstract class AbstractWorkerChoiceStrategy<Worker extends IPoolWorker, Data, Response> implements IWorkerChoiceStrategy<Worker> {
export declare abstract class AbstractWorkerChoiceStrategy<Worker extends IPoolWorker, Data, Response> implements IWorkerChoiceStrategy {
protected readonly pool: IPoolInternal<Worker, Data, Response>;

@@ -27,3 +27,5 @@ /** {@inheritDoc} */

/** {@inheritDoc} */
abstract choose(): Worker;
abstract choose(): number;
/** {@inheritDoc} */
abstract remove(workerKey: number): boolean;
}

@@ -13,3 +13,3 @@ import type { IPoolInternal } from '../pool-internal';

export declare class DynamicPoolWorkerChoiceStrategy<Worker extends IPoolWorker, Data, Response> extends AbstractWorkerChoiceStrategy<Worker, Data, Response> {
private readonly createDynamicallyWorkerCallback;
private readonly createWorkerCallback;
private readonly workerChoiceStrategy;

@@ -20,10 +20,12 @@ /**

* @param pool - The pool instance.
* @param createDynamicallyWorkerCallback - The worker creation callback for dynamic pool.
* @param workerChoiceStrategy - The worker choice strategy when the pull is busy.
* @param createWorkerCallback - The worker creation callback for dynamic pool.
* @param workerChoiceStrategy - The worker choice strategy when the pool is busy.
*/
constructor(pool: IPoolInternal<Worker, Data, Response>, createDynamicallyWorkerCallback: () => Worker, workerChoiceStrategy?: WorkerChoiceStrategy);
constructor(pool: IPoolInternal<Worker, Data, Response>, createWorkerCallback: () => number, workerChoiceStrategy?: WorkerChoiceStrategy);
/** {@inheritDoc} */
reset(): boolean;
/** {@inheritDoc} */
choose(): Worker;
choose(): number;
/** {@inheritDoc} */
remove(workerKey: number): boolean;
}

@@ -22,9 +22,11 @@ import type { IPoolWorker } from '../pool-worker';

/** {@inheritDoc} */
choose(): Worker;
choose(): number;
/** {@inheritDoc} */
remove(workerKey: number): boolean;
/**
* Computes worker last virtual task timestamp.
*
* @param worker - The worker.
* @param workerKey - The worker key.
*/
private computeWorkerLastVirtualTaskTimestamp;
}

@@ -12,9 +12,11 @@ import type { IPoolWorker } from '../pool-worker';

/**
* Index for the next worker.
* Id of the next worker.
*/
private nextWorkerIndex;
private nextWorkerId;
/** {@inheritDoc} */
reset(): boolean;
/** {@inheritDoc} */
choose(): Worker;
choose(): number;
/** {@inheritDoc} */
remove(workerKey: number): boolean;
}

@@ -1,2 +0,1 @@

import type { IPoolWorker } from '../pool-worker';
/**

@@ -11,6 +10,10 @@ * Enumeration of worker choice strategies.

/**
* Less recently used worker selection strategy.
* Less used worker selection strategy.
*/
readonly LESS_RECENTLY_USED: "LESS_RECENTLY_USED";
readonly LESS_USED: "LESS_USED";
/**
* Less busy worker selection strategy.
*/
readonly LESS_BUSY: "LESS_BUSY";
/**
* Fair share worker selection strategy.

@@ -36,6 +39,4 @@ */

* Worker choice strategy interface.
*
* @typeParam Worker - Type of worker which manages the strategy.
*/
export interface IWorkerChoiceStrategy<Worker extends IPoolWorker> {
export interface IWorkerChoiceStrategy {
/**

@@ -54,5 +55,11 @@ * Is the pool attached to the strategy dynamic?.

/**
* Chooses a worker in the pool.
* Chooses a worker in the pool and returns its key.
*/
choose: () => Worker;
choose: () => number;
/**
* Removes a worker reference from strategy internals.
*
* @param workerKey - The worker key.
*/
remove: (workerKey: number) => boolean;
}

@@ -11,2 +11,2 @@ import type { IPoolInternal } from '../pool-internal';

*/
export declare function getWorkerChoiceStrategy<Worker extends IPoolWorker, Data, Response>(pool: IPoolInternal<Worker, Data, Response>, workerChoiceStrategy?: WorkerChoiceStrategy): IWorkerChoiceStrategy<Worker>;
export declare function getWorkerChoiceStrategy<Worker extends IPoolWorker, Data, Response>(pool: IPoolInternal<Worker, Data, Response>, workerChoiceStrategy?: WorkerChoiceStrategy): IWorkerChoiceStrategy;

@@ -17,5 +17,5 @@ import type { IPoolInternal } from '../pool-internal';

/**
* Worker index where the current task will be submitted.
* Worker id where the current task will be submitted.
*/
private currentWorkerIndex;
private currentWorkerId;
/**

@@ -38,3 +38,5 @@ * Default worker weight.

/** {@inheritDoc} */
choose(): Worker;
choose(): number;
/** {@inheritDoc} */
remove(workerKey: number): boolean;
private initWorkersTaskRunTime;

@@ -41,0 +43,0 @@ private initWorkerTaskRunTime;

import type { IPoolInternal } from '../pool-internal';
import type { IPoolWorker } from '../pool-worker';
import type { IWorkerChoiceStrategy, WorkerChoiceStrategy } from './selection-strategies-types';
import type { IWorkerChoiceStrategy, RequiredStatistics, WorkerChoiceStrategy } from './selection-strategies-types';
/**

@@ -13,3 +13,3 @@ * The worker choice strategy context.

private readonly pool;
private readonly createDynamicallyWorkerCallback;
private readonly createWorkerCallback;
private workerChoiceStrategy;

@@ -20,6 +20,6 @@ /**

* @param pool - The pool instance.
* @param createDynamicallyWorkerCallback - The worker creation callback for dynamic pool.
* @param createWorkerCallback - The worker creation callback for dynamic pool.
* @param workerChoiceStrategy - The worker choice strategy.
*/
constructor(pool: IPoolInternal<Worker, Data, Response>, createDynamicallyWorkerCallback: () => Worker, workerChoiceStrategy?: WorkerChoiceStrategy);
constructor(pool: IPoolInternal<Worker, Data, Response>, createWorkerCallback: () => number, workerChoiceStrategy?: WorkerChoiceStrategy);
/**

@@ -36,5 +36,12 @@ * Gets the worker choice strategy instance specific to the pool type.

* @returns The worker choice strategy.
* @deprecated Scheduled removal.
*/
getWorkerChoiceStrategy(): IWorkerChoiceStrategy<Worker>;
getWorkerChoiceStrategy(): IWorkerChoiceStrategy;
/**
* Gets the worker choice strategy required statistics.
*
* @returns The required statistics.
*/
getRequiredStatistics(): RequiredStatistics;
/**
* Sets the worker choice strategy to use in the context.

@@ -48,5 +55,12 @@ *

*
* @returns The chosen one.
* @returns The key of the chosen one.
*/
execute(): Worker;
execute(): number;
/**
* Removes a worker in the underlying selection strategy internals.
*
* @param workerKey - The key of the worker to remove.
* @returns `true` if the removal is successful, `false` otherwise.
*/
remove(workerKey: number): boolean;
}
/// <reference types="node" />
import { MessageChannel, Worker } from 'worker_threads';
import { MessageChannel, Worker } from 'node:worker_threads';
import type { Draft, MessageValue } from '../../utility-types';

@@ -4,0 +4,0 @@ import { AbstractPool } from '../abstract-pool';

/// <reference types="node" />
/// <reference types="node" />
import type { Worker as ClusterWorker } from 'cluster';
import type { MessagePort } from 'worker_threads';
import type { Worker as ClusterWorker } from 'node:cluster';
import type { MessagePort } from 'node:worker_threads';
import type { KillBehavior } from './worker/worker-options';
import type { IPoolWorker } from './pools/pool-worker';
import type { KillBehavior } from './worker/worker-options';
/**

@@ -24,3 +24,3 @@ * Make all properties in T non-readonly.

*/
readonly id?: number;
readonly id?: string;
/**

@@ -46,8 +46,8 @@ * Kill code.

/**
* An object holding the worker that will be used to resolve/rejects the promise later on.
* An object holding the execution response promise resolve/reject callbacks.
*
* @typeParam Worker - Type of worker.
* @typeParam Response - Type of response of execution. This can only be serializable data.
* @typeParam Response - Type of execution response. This can only be serializable data.
*/
export interface PromiseWorkerResponseWrapper<Worker extends IPoolWorker, Response = unknown> {
export interface PromiseResponseWrapper<Worker extends IPoolWorker, Response = unknown> {
/**

@@ -62,5 +62,5 @@ * Resolve callback to fulfill the promise.

/**
* The worker that has the assigned task.
* The worker handling the promise.
*/
readonly worker: Worker;
}

@@ -5,7 +5,7 @@ /// <reference types="node" />

/// <reference types="node" />
import { AsyncResource } from 'async_hooks';
import type { Worker } from 'cluster';
import type { MessagePort } from 'worker_threads';
import { AsyncResource } from 'node:async_hooks';
import type { Worker } from 'node:cluster';
import type { MessagePort } from 'node:worker_threads';
import type { MessageValue } from '../utility-types';
import type { WorkerOptions } from './worker-options';
import { type WorkerOptions } from './worker-options';
/**

@@ -12,0 +12,0 @@ * Base class that implements some shared logic for all poolifier workers.

/// <reference types="node" />
import type { Worker } from 'cluster';
import type { Worker } from 'node:cluster';
import type { MessageValue } from '../utility-types';

@@ -4,0 +4,0 @@ import { AbstractWorker } from './abstract-worker';

/// <reference types="node" />
import type { MessagePort } from 'worker_threads';
import type { MessagePort } from 'node:worker_threads';
import type { MessageValue } from '../utility-types';

@@ -4,0 +4,0 @@ import { AbstractWorker } from './abstract-worker';

@@ -10,3 +10,3 @@ /**

/**
* If `lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.
* If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.
*/

@@ -55,3 +55,3 @@ readonly HARD: "HARD";

* - SOFT: If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker **won't** be deleted.
* - HARD: If `lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.
* - HARD: If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.
*

@@ -58,0 +58,0 @@ * This option only apply to the newly created workers.

{
"name": "poolifier",
"version": "2.3.10",
"version": "2.4.0-2",
"description": "A fast, easy to use Node.js Worker Thread Pool and Cluster Pool implementation",

@@ -13,22 +13,2 @@ "license": "MIT",

},
"scripts": {
"prepare": "node prepare.js",
"build": "rollup --config --environment BUILD:development",
"build:typedoc": "rollup --config --environment BUILD:development --environment DOCUMENTATION",
"build:prod": "rollup --config",
"benchmark": "npm run build && node -r source-map-support/register benchmarks/internal/bench.js",
"benchmark:debug": "npm run build && node -r source-map-support/register --inspect benchmarks/internal/bench.js",
"benchmark:prod": "npm run build:prod && node -r source-map-support/register benchmarks/internal/bench.js",
"test": "npm run build && c8 mocha 'tests/**/*.test.js'",
"test:debug": "npm run build && mocha --no-parallel --inspect 'tests/**/*.test.js'",
"coverage": "c8 report --reporter=lcov",
"coverage:html": "c8 report --reporter=html",
"format": "prettier . --cache --write; ts-standard . --fix",
"lint": "eslint . --cache",
"lint:fix": "eslint . --cache --fix",
"lint:report": "eslint . --cache --format json --output-file reports/eslint.json",
"release": "release-it",
"typedoc": "typedoc",
"prepublishOnly": "npm run build:prod"
},
"ts-standard": {

@@ -45,4 +25,3 @@ "globals": [

"engines": {
"node": ">=16.0.0",
"npm": ">=8.0.0"
"node": ">=16.0.0"
},

@@ -85,2 +64,6 @@ "repository": {

"url": "https://opencollective.com/poolifier"
},
{
"type": "github",
"url": "https://github.com/sponsors/poolifier"
}

@@ -96,3 +79,3 @@ ],

"devDependencies": {
"@commitlint/cli": "^17.4.4",
"@commitlint/cli": "^17.5.1",
"@commitlint/config-conventional": "^17.4.4",

@@ -103,15 +86,15 @@ "@release-it/bumper": "^4.0.2",

"@rollup/plugin-typescript": "^11.0.0",
"@types/node": "^18.15.3",
"@typescript-eslint/eslint-plugin": "^5.55.0",
"@typescript-eslint/parser": "^5.55.0",
"@types/node": "^18.15.11",
"@typescript-eslint/eslint-plugin": "^5.57.1",
"@typescript-eslint/parser": "^5.57.1",
"benny": "^3.7.1",
"c8": "^7.13.0",
"eslint": "^8.36.0",
"eslint": "^8.37.0",
"eslint-config-standard": "^17.0.0",
"eslint-config-standard-with-typescript": "^34.0.1",
"eslint-define-config": "^1.17.0",
"eslint-import-resolver-typescript": "^3.5.3",
"eslint-import-resolver-typescript": "^3.5.4",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsdoc": "^40.0.3",
"eslint-plugin-n": "^15.6.1",
"eslint-plugin-jsdoc": "^40.1.1",
"eslint-plugin-n": "^15.7.0",
"eslint-plugin-promise": "^6.1.1",

@@ -126,15 +109,34 @@ "eslint-plugin-spellcheck": "^0.0.20",

"mochawesome": "^7.1.3",
"prettier": "^2.8.4",
"prettier": "^2.8.7",
"prettier-plugin-organize-imports": "^3.2.2",
"release-it": "^15.9.0",
"rollup": "^3.19.1",
"release-it": "^15.10.1",
"rollup": "^3.20.2",
"rollup-plugin-analyzer": "^4.0.0",
"rollup-plugin-command": "^1.1.3",
"rollup-plugin-delete": "^2.0.0",
"sinon": "^15.0.2",
"sinon": "^15.0.3",
"source-map-support": "^0.5.21",
"ts-standard": "^12.0.2",
"typedoc": "^0.23.27",
"typescript": "^5.0.2"
"typedoc": "^0.23.28",
"typescript": "^5.0.3"
},
"scripts": {
"preinstall": "npx only-allow pnpm",
"build": "rollup --config --environment BUILD:development",
"build:typedoc": "rollup --config --environment BUILD:development --environment DOCUMENTATION",
"build:prod": "rollup --config",
"benchmark": "pnpm run build && node -r source-map-support/register benchmarks/internal/bench.js",
"benchmark:debug": "pnpm run build && node -r source-map-support/register --inspect benchmarks/internal/bench.js",
"benchmark:prod": "pnpm run build:prod && node -r source-map-support/register benchmarks/internal/bench.js",
"test": "pnpm run build && c8 mocha 'tests/**/*.test.js'",
"test:debug": "pnpm run build && mocha --no-parallel --inspect 'tests/**/*.test.js'",
"coverage": "c8 report --reporter=lcov",
"coverage:html": "c8 report --reporter=html",
"format": "prettier . --cache --write; ts-standard . --fix",
"lint": "eslint . --cache",
"lint:fix": "eslint . --cache --fix",
"lint:report": "eslint . --cache --format json --output-file reports/eslint.json",
"release": "release-it",
"typedoc": "typedoc"
}
}

@@ -166,3 +166,4 @@ <div align="center">

- `WorkerChoiceStrategies.ROUND_ROBIN`: Submit tasks to worker in a round robbin fashion
- `WorkerChoiceStrategies.LESS_RECENTLY_USED`: Submit tasks to the less recently used worker
- `WorkerChoiceStrategies.LESS_USED`: Submit tasks to the less used worker
- `WorkerChoiceStrategies.LESS_BUSY`: Submit tasks to the less busy worker
- `WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN` Submit tasks to worker using a weighted round robin scheduling algorithm based on tasks execution time

@@ -207,3 +208,3 @@ - `WorkerChoiceStrategies.FAIR_SHARE`: Submit tasks to worker using a fair share tasks scheduling algorithm based on tasks execution time

**KillBehaviors.SOFT**: If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker **won't** be deleted.
**KillBehaviors.HARD**: If `lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.
**KillBehaviors.HARD**: If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.
This option only apply to the newly created workers.

@@ -210,0 +211,0 @@ Default: `KillBehaviors.SOFT`

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc