poolifier 5.3.0 → 5.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import e,{Worker as t}from"node:cluster";import{existsSync as r}from"node:fs";import{env as s}from"node:process";import{Worker as i,SHARE_ENV as o,MessageChannel as n,isMainThread as a,threadId as u,parentPort as h}from"node:worker_threads";import{getRandomValues as k,randomUUID as d}from"node:crypto";import*as l from"node:os";import{cpus as c}from"node:os";import{AsyncResource as m}from"node:async_hooks";import{EventEmitter as g,EventEmitterAsyncResource as w}from"node:events";import{performance as y}from"node:perf_hooks";const p=Object.freeze({dynamic:"dynamic",fixed:"fixed"}),f=Object.freeze({backPressure:"backPressure",backPressureEnd:"backPressureEnd",busy:"busy",busyEnd:"busyEnd",destroy:"destroy",empty:"empty",error:"error",full:"full",fullEnd:"fullEnd",ready:"ready",taskError:"taskError"}),N=1/1.5,T="default",W=Object.freeze(()=>{}),E=()=>{let e=1;try{e=l.availableParallelism()}catch{const t=l.cpus();Array.isArray(t)&&t.length>0&&(e=t.length)}return e},S=e=>Array.isArray(e)&&0!==e.length?1===e.length?e[0]:e.reduce((e,t)=>e+t,0)/e.length:0,b=e=>{if(!Array.isArray(e)||0===e.length)return 0;if(1===e.length)return e[0];const t=e.slice().sort((e,t)=>e-t);return(t[t.length-1>>1]+t[t.length>>1])/2},v=(e,t=2)=>{const r=10**t;return Math.round((e+Math.sign(e)*Number.EPSILON)*r)/r},x=e=>"object"==typeof e&&null!==e&&e.constructor===Object&&"[object Object]"===Object.prototype.toString.call(e),I=(e,t)=>t===e,F=e=>e?.constructor===(async()=>{}).constructor,O=()=>k(new Uint32Array(1))[0]/4294967296,C=(...e)=>e.reduce((e,t)=>e<t?e:t,Number.POSITIVE_INFINITY),P=(...e)=>e.reduce((e,t)=>e>t?e:t,Number.NEGATIVE_INFINITY),A=(e,t)=>({name:e,...null!=t?.priority&&{priority:t.priority},...null!=t?.strategy&&{strategy:t.strategy},...null!=t?.workerNodeKeys&&{workerNodeKeys:t.workerNodeKeys}}),z=Object.freeze({FAIR_SHARE:"FAIR_SHARE",INTERLEAVED_WEIGHTED_ROUND_ROBIN:"INTERLEAVED_WEIGHTED_ROUND_ROBIN",LEAST_BUSY:"LEAST_BUSY",LEAST_ELU:"LEAST_ELU",LEAST_USED:"LEAST_USED",ROUND_ROBIN:"ROUND_ROBIN",WEIGHTED_ROUND_ROBIN:"WEIGHTED_ROUND_ROBIN"}),R=Object.freeze({elu:"elu",runTime:"runTime",waitTime:"waitTime"}),K=386,q=Object.freeze({cluster:"cluster",thread:"thread"}),M=Object.freeze({aggregate:!1,average:!1,median:!1}),Q=e=>Object.freeze({agingFactor:.001,concurrency:1,loadExponent:N,size:e**2,tasksFinishedTimeout:2e3,tasksStealingOnBackPressure:!0,tasksStealingRatio:.6,taskStealing:!0}),D=e=>{if(null==e)throw new TypeError("The worker file path must be defined");if("string"!=typeof e)throw new TypeError("The worker file path must be a string");if(!r(e))throw new Error(`Cannot find the worker file '${e}'`)},U=(e,t)=>{if(null==t)throw new TypeError("Cannot instantiate a dynamic pool without specifying the maximum pool size");if(!Number.isSafeInteger(t))throw new TypeError("Cannot instantiate a dynamic pool with a non safe integer maximum pool size");if(e>t)throw new RangeError("Cannot instantiate a dynamic pool with a maximum pool size inferior to the minimum pool size");if(0===t)throw new RangeError("Cannot instantiate a dynamic pool with a maximum pool size equal to zero");if(e===t)throw new RangeError("Cannot instantiate a dynamic pool with a minimum pool size equal to the maximum pool size. Use a fixed pool instead")},B=e=>{if(null!=e&&!Number.isSafeInteger(e))throw new TypeError(`Invalid property 'priority': '${e.toString()}'`);if(null!=e&&Number.isSafeInteger(e)&&(e<-20||e>19))throw new RangeError("Property 'priority' must be between -20 and 19")},_=e=>{if(null!=e&&!Object.values(z).includes(e))throw new Error(`Invalid worker choice strategy '${e}'`)},L=(e,t)=>{if(null!=e&&!Array.isArray(e))throw new TypeError("Invalid worker node keys: must be an array");if(0===e?.length)throw new RangeError("Invalid worker node keys: must not be an empty array");if(null!=e)for(const t of e)if(!Number.isSafeInteger(t)||t<0)throw new TypeError(`Invalid worker node key '${t.toString()}': must be a non-negative safe integer`);if(null!=e&&new Set(e).size!==e.length)throw new TypeError("Invalid worker node keys: must not contain duplicates");if(null!=t&&null!=e){if(e.length>t)throw new RangeError("Cannot add a task function with more worker node keys than the maximum number of workers in the pool");const r=e.filter(e=>e>=t);if(r.length>0)throw new RangeError(`Cannot add a task function with invalid worker node keys: ${r.toString()}. Valid keys are: 0..${(t-1).toString()}`)}},$=e=>{if(null!=e&&!x(e))throw new TypeError("Invalid tasks queue options: must be a plain object");if(null!=e?.concurrency&&!Number.isSafeInteger(e.concurrency))throw new TypeError("Invalid worker node tasks concurrency: must be an integer");if(null!=e?.concurrency&&e.concurrency<=0)throw new RangeError(`Invalid worker node tasks concurrency: ${e.concurrency.toString()} is a negative integer or zero`);if(null!=e?.size&&!Number.isSafeInteger(e.size))throw new TypeError("Invalid worker node tasks queue size: must be an integer");if(null!=e?.size&&e.size<=0)throw new RangeError(`Invalid worker node tasks queue size: ${e.size.toString()} is a negative integer or zero`);if(null!=e?.agingFactor&&"number"!=typeof e.agingFactor)throw new TypeError("Invalid worker node tasks queue aging factor: must be a number");if(null!=e?.agingFactor&&e.agingFactor<0)throw new RangeError("Invalid worker node tasks queue aging factor: must be greater than or equal to 0");if(null!=e?.loadExponent&&"number"!=typeof e.loadExponent)throw new TypeError("Invalid worker node tasks queue load exponent: must be a number");if(null!=e?.loadExponent&&e.loadExponent<=0)throw new RangeError("Invalid worker node tasks queue load exponent: must be greater than 0");if(null!=e?.tasksStealingRatio&&"number"!=typeof e.tasksStealingRatio)throw new TypeError("Invalid worker node tasks stealing ratio: must be a number");if(null!=e?.tasksStealingRatio&&(e.tasksStealingRatio<0||e.tasksStealingRatio>1))throw new RangeError("Invalid worker node tasks stealing ratio: must be between 0 and 1")},V=(e,t,r)=>{null!=t&&null!=r&&t.aggregate&&(e.aggregate=(e.aggregate??0)+r,e.minimum=C(r,e.minimum??Number.POSITIVE_INFINITY),e.maximum=P(r,e.maximum??Number.NEGATIVE_INFINITY),(t.average||t.median)&&(e.history.put(r),t.average?e.average=S(e.history.toArray()):null!=e.average&&(e.average=void 0),t.median?e.median=b(e.history.toArray()):null!=e.median&&(e.median=void 0)))};"test"===s.NODE_ENV&&(exports.updateMeasurementStatistics=V);const H=(e,t,r)=>{const s=performance.now(),i=s-(r.timestamp??s);V(t.waitTime,e?.getTaskStatisticsRequirements().waitTime,i)},j=(e,t)=>{const r=e.tasks;null!=r.executing&&r.executing>0&&--r.executing,null==t.workerError?++r.executed:++r.failed},Y=(e,t,r)=>{null==r.workerError&&V(t.runTime,e?.getTaskStatisticsRequirements().runTime,r.taskPerformance?.runTime??0)},G=(e,t,r)=>{if(null!=r.workerError)return;const s=e?.getTaskStatisticsRequirements().elu;V(t.elu.active,s,r.taskPerformance?.elu?.active??0),V(t.elu.idle,s,r.taskPerformance?.elu?.idle??0),!0===s?.aggregate&&null!=r.taskPerformance?.elu&&(t.elu.count=(t.elu.count??0)+1,t.elu.utilization=((t.elu.utilization??0)*(t.elu.count-1)+r.taskPerformance.elu.utilization)/t.elu.count)},J=e=>e instanceof i?q.thread:e instanceof t?q.cluster:void 0,X=e=>e instanceof i?e.threadId:e instanceof t?e.id:void 0,Z=Object.freeze({HARD:"HARD",SOFT:"SOFT"});class ee{pool;opts;retriesCount;strategyPolicy=Object.freeze({dynamicWorkerReady:!0,dynamicWorkerUsage:!1});taskStatisticsRequirements=Object.freeze({elu:{...M},runTime:{...M},waitTime:{...M}});nextWorkerNodeKey;previousWorkerNodeKey;constructor(e,t){this.pool=e,this.opts=t,this.retriesCount=0,this.nextWorkerNodeKey=0,this.previousWorkerNodeKey=0,this.choose=this.choose.bind(this),this.setOptions(this.opts)}setOptions(e){this.opts=ke(this.pool,e),this.setTaskStatisticsRequirements(this.opts)}checkWorkerNodeKey(e){if(!(null==e||e<0||e>=this.pool.workerNodes.length))return e}getRoundRobinNextWorkerNodeKey(){return this.nextWorkerNodeKey===this.pool.workerNodes.length-1?0:(this.nextWorkerNodeKey??this.previousWorkerNodeKey)+1}getSingleWorkerNodeKey(e){const[t]=e;return this.isWorkerNodeReady(t)?t:void 0}getWorkerNodeTaskElu(e){return this.taskStatisticsRequirements.elu.median?this.pool.workerNodes[e]?.usage.elu.active.median??0:this.pool.workerNodes[e]?.usage.elu.active.average??0}getWorkerNodeTaskRunTime(e){return this.taskStatisticsRequirements.runTime.median?this.pool.workerNodes[e]?.usage.runTime.median??0:this.pool.workerNodes[e]?.usage.runTime.average??0}getWorkerNodeTaskWaitTime(e){return this.taskStatisticsRequirements.waitTime.median?this.pool.workerNodes[e]?.usage.waitTime.median??0:this.pool.workerNodes[e]?.usage.waitTime.average??0}isWorkerNodeEligible(e,t){return this.isWorkerNodeReady(e)&&(null==t||t.has(e))}isWorkerNodeReady(e){return this.pool.workerNodes[e]?.info.ready??!1}resetWorkerNodeKeyProperties(){this.nextWorkerNodeKey=0,this.previousWorkerNodeKey=0}setPreviousWorkerNodeKey(e){this.previousWorkerNodeKey=null!=e&&e>=0&&e<this.pool.workerNodes.length?e:this.previousWorkerNodeKey}setTaskStatisticsRequirements(e){de(this.taskStatisticsRequirements.runTime,e.runTime.median),de(this.taskStatisticsRequirements.waitTime,e.waitTime.median),de(this.taskStatisticsRequirements.elu,e.elu.median)}}class te extends ee{name=z.FAIR_SHARE;taskStatisticsRequirements=Object.freeze({elu:{aggregate:!0,average:!0,median:!1},runTime:{aggregate:!0,average:!0,median:!1},waitTime:{aggregate:!0,average:!0,median:!1}});constructor(e,t){super(e,t),this.setTaskStatisticsRequirements(this.opts)}choose(e){return this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey),this.nextWorkerNodeKey=this.fairShareNextWorkerNodeKey(e),this.nextWorkerNodeKey}remove(e){return null!=this.pool.workerNodes[e]?.strategyData?.virtualTaskEndTimestamp&&(this.pool.workerNodes[e].strategyData.virtualTaskEndTimestamp=void 0),!0}reset(){for(const e of this.pool.workerNodes)null!=e.strategyData?.virtualTaskEndTimestamp&&(e.strategyData.virtualTaskEndTimestamp=void 0);return!0}update(e){return this.pool.workerNodes[e].strategyData={...this.pool.workerNodes[e].strategyData,virtualTaskEndTimestamp:this.computeWorkerNodeVirtualTaskEndTimestamp(e)},!0}computeWorkerNodeVirtualTaskEndTimestamp(e){return this.getWorkerNodeVirtualTaskEndTimestamp(e,this.getWorkerNodeVirtualTaskStartTimestamp(e))}fairShareNextWorkerNodeKey(e){if(0===e?.size)return;if(1===e?.size)return this.getSingleWorkerNodeKey(e);const t=this.pool.workerNodes.reduce((t,r,s,i)=>this.isWorkerNodeEligible(s,e)?(null==r.strategyData?.virtualTaskEndTimestamp&&(r.strategyData={...r.strategyData,virtualTaskEndTimestamp:this.computeWorkerNodeVirtualTaskEndTimestamp(s)}),-1===t||r.strategyData.virtualTaskEndTimestamp<i[t].strategyData.virtualTaskEndTimestamp?s:t):t,-1);return-1===t?void 0:t}getWorkerNodeVirtualTaskEndTimestamp(e,t){return t+(this.getWorkerNodeTaskWaitTime(e)+(this.opts?.measurement===R.elu?this.getWorkerNodeTaskElu(e):this.getWorkerNodeTaskRunTime(e)))}getWorkerNodeVirtualTaskStartTimestamp(e){const t=this.pool.workerNodes[e]?.strategyData?.virtualTaskEndTimestamp,r=performance.now();return r<(t??Number.NEGATIVE_INFINITY)?t:r}}class re extends ee{name=z.INTERLEAVED_WEIGHTED_ROUND_ROBIN;taskStatisticsRequirements=Object.freeze({elu:{...M},runTime:{aggregate:!0,average:!0,median:!1},waitTime:{aggregate:!0,average:!0,median:!1}});roundId=0;roundWeights;workerNodeId=0;workerNodeVirtualTaskExecutionTime=0;constructor(e,t){super(e,t),this.setTaskStatisticsRequirements(this.opts),this.roundWeights=this.getRoundWeights()}choose(e){if(0!==e?.size){if(1===e?.size)return this.getSingleWorkerNodeKey(e);for(let t=this.roundId;t<this.roundWeights.length;t++){this.roundId=t;for(let r=this.workerNodeId;r<this.pool.workerNodes.length;r++){this.workerNodeId=r,this.workerNodeId!==this.nextWorkerNodeKey&&0!==this.workerNodeVirtualTaskExecutionTime&&(this.workerNodeVirtualTaskExecutionTime=0);const s=this.opts.weights[r];if(this.isWorkerNodeEligible(r,e)&&s>=this.roundWeights[t]&&this.workerNodeVirtualTaskExecutionTime<s)return this.workerNodeVirtualTaskExecutionTime+=this.getWorkerNodeTaskWaitTime(r)+this.getWorkerNodeTaskRunTime(r),this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey),this.nextWorkerNodeKey=r,this.nextWorkerNodeKey}this.workerNodeId=0}this.interleavedWeightedRoundRobinNextWorkerNodeId()}}remove(e){return 0===this.pool.workerNodes.length?(this.resetWorkerNodeKeyProperties(),this.workerNodeId=0,this.workerNodeVirtualTaskExecutionTime=0,!0):(null!=this.nextWorkerNodeKey&&this.nextWorkerNodeKey>=e&&(this.nextWorkerNodeKey=(this.nextWorkerNodeKey-1+this.pool.workerNodes.length)%this.pool.workerNodes.length),this.workerNodeId>=e&&(this.workerNodeId=(this.workerNodeId-1+this.pool.workerNodes.length)%this.pool.workerNodes.length),!0)}reset(){return this.resetWorkerNodeKeyProperties(),this.roundId=0,this.workerNodeId=0,this.workerNodeVirtualTaskExecutionTime=0,!0}setOptions(e){super.setOptions(e),this.roundWeights=this.getRoundWeights()}update(){return!0}getRoundWeights(){return[...new Set(Object.values(this.opts.weights).slice().sort((e,t)=>e-t))]}interleavedWeightedRoundRobinNextWorkerNodeId(){0===this.pool.workerNodes.length?this.workerNodeId=0:this.roundId===this.roundWeights.length-1&&this.workerNodeId===this.pool.workerNodes.length-1?(this.roundId=0,this.workerNodeId=0):this.workerNodeId===this.pool.workerNodes.length-1?(this.roundId=this.roundId+1,this.workerNodeId=0):this.workerNodeId=this.workerNodeId+1}}class se extends ee{name=z.LEAST_BUSY;taskStatisticsRequirements=Object.freeze({elu:{...M},runTime:{aggregate:!0,average:!1,median:!1},waitTime:{aggregate:!0,average:!1,median:!1}});constructor(e,t){super(e,t),this.setTaskStatisticsRequirements(this.opts)}choose(e){return this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey),this.nextWorkerNodeKey=this.leastBusyNextWorkerNodeKey(e),this.nextWorkerNodeKey}remove(){return!0}reset(){return!0}update(){return!0}leastBusyNextWorkerNodeKey(e){if(0===e?.size)return;if(1===e?.size)return this.getSingleWorkerNodeKey(e);const t=this.pool.workerNodes.reduce((t,r,s,i)=>this.isWorkerNodeEligible(s,e)&&(-1===t||(r.usage.waitTime.aggregate??0)+(r.usage.runTime.aggregate??0)<(i[t].usage.waitTime.aggregate??0)+(i[t].usage.runTime.aggregate??0))?s:t,-1);return-1===t?void 0:t}}class ie extends ee{name=z.LEAST_ELU;taskStatisticsRequirements=Object.freeze({elu:{aggregate:!0,average:!1,median:!1},runTime:{...M},waitTime:{aggregate:!0,average:!1,median:!1}});constructor(e,t){super(e,t),this.setTaskStatisticsRequirements(this.opts)}choose(e){return this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey),this.nextWorkerNodeKey=this.leastEluNextWorkerNodeKey(e),this.nextWorkerNodeKey}remove(){return!0}reset(){return!0}update(){return!0}leastEluNextWorkerNodeKey(e){if(0===e?.size)return;if(1===e?.size)return this.getSingleWorkerNodeKey(e);const t=this.pool.workerNodes.reduce((t,r,s,i)=>this.isWorkerNodeEligible(s,e)&&(-1===t||(r.usage.waitTime.aggregate??0)+(r.usage.elu.active.aggregate??0)<(i[t].usage.waitTime.aggregate??0)+(i[t].usage.elu.active.aggregate??0))?s:t,-1);return-1===t?void 0:t}}class oe extends ee{name=z.LEAST_USED;constructor(e,t){super(e,t)}choose(e){return this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey),this.nextWorkerNodeKey=this.leastUsedNextWorkerNodeKey(e),this.nextWorkerNodeKey}remove(){return!0}reset(){return!0}update(){return!0}leastUsedNextWorkerNodeKey(e){if(0===e?.size)return;if(1===e?.size)return this.getSingleWorkerNodeKey(e);const t=this.pool.workerNodes.reduce((t,r,s,i)=>this.isWorkerNodeEligible(s,e)&&(-1===t||r.usage.tasks.executing+r.usage.tasks.queued<i[t].usage.tasks.executing+i[t].usage.tasks.queued)?s:t,-1);return-1===t?void 0:t}}class ne extends ee{name=z.ROUND_ROBIN;constructor(e,t){super(e,t)}choose(e){this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey);const t=this.roundRobinNextWorkerNodeKey(e);if(null!=t&&this.isWorkerNodeEligible(t,e))return this.checkWorkerNodeKey(t)}remove(e){return 0===this.pool.workerNodes.length?this.reset():(null!=this.nextWorkerNodeKey&&this.nextWorkerNodeKey>=e&&(this.nextWorkerNodeKey=(this.nextWorkerNodeKey-1+this.pool.workerNodes.length)%this.pool.workerNodes.length,this.previousWorkerNodeKey>=e&&(this.previousWorkerNodeKey=this.nextWorkerNodeKey)),!0)}reset(){return this.resetWorkerNodeKeyProperties(),!0}update(){return!0}roundRobinNextWorkerNodeKey(e){if(null==e)return this.nextWorkerNodeKey=this.getRoundRobinNextWorkerNodeKey(),this.nextWorkerNodeKey;if(0===e.size)return;if(1===e.size){const t=this.getSingleWorkerNodeKey(e);return null!=t&&(this.nextWorkerNodeKey=t),t}const t=this.pool.workerNodes.length;for(let r=0;r<t;r++)if(this.nextWorkerNodeKey=this.getRoundRobinNextWorkerNodeKey(),e.has(this.nextWorkerNodeKey))return this.nextWorkerNodeKey}}class ae extends ee{name=z.WEIGHTED_ROUND_ROBIN;taskStatisticsRequirements=Object.freeze({elu:{...M},runTime:{aggregate:!0,average:!0,median:!1},waitTime:{aggregate:!0,average:!0,median:!1}});workerNodeVirtualTaskExecutionTime=0;constructor(e,t){super(e,t),this.setTaskStatisticsRequirements(this.opts)}choose(e){this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey);const t=this.weightedRoundRobinNextWorkerNodeKey(e);if(null!=t&&this.isWorkerNodeEligible(t,e))return this.checkWorkerNodeKey(t)}remove(e){return 0===this.pool.workerNodes.length?this.reset():(this.nextWorkerNodeKey===e&&(this.workerNodeVirtualTaskExecutionTime=0),null!=this.nextWorkerNodeKey&&this.nextWorkerNodeKey>=e&&(this.nextWorkerNodeKey=(this.nextWorkerNodeKey-1+this.pool.workerNodes.length)%this.pool.workerNodes.length,this.previousWorkerNodeKey>=e&&(this.previousWorkerNodeKey=this.nextWorkerNodeKey)),!0)}reset(){return this.resetWorkerNodeKeyProperties(),this.workerNodeVirtualTaskExecutionTime=0,!0}update(){return!0}findEligibleWorkerNodeKey(e){const t=this.pool.workerNodes.length;for(let r=0;r<t;r++)if(this.nextWorkerNodeKey=this.getRoundRobinNextWorkerNodeKey(),e.has(this.nextWorkerNodeKey))return this.nextWorkerNodeKey}weightedRoundRobinNextWorkerNodeKey(e){if(null==e){const e=this.nextWorkerNodeKey??this.previousWorkerNodeKey,t=this.opts.weights[e];return this.workerNodeVirtualTaskExecutionTime<t?(this.nextWorkerNodeKey=e,this.workerNodeVirtualTaskExecutionTime+=this.getWorkerNodeTaskWaitTime(e)+this.getWorkerNodeTaskRunTime(e)):(this.nextWorkerNodeKey=this.getRoundRobinNextWorkerNodeKey(),this.workerNodeVirtualTaskExecutionTime=0),this.nextWorkerNodeKey}if(0===e.size)return;if(1===e.size){const t=this.getSingleWorkerNodeKey(e);return null!=t&&(this.nextWorkerNodeKey=t,this.workerNodeVirtualTaskExecutionTime=0),t}const t=this.nextWorkerNodeKey??this.previousWorkerNodeKey;if(!e.has(t))return this.nextWorkerNodeKey=this.findEligibleWorkerNodeKey(e),this.workerNodeVirtualTaskExecutionTime=0,this.nextWorkerNodeKey;const r=this.opts.weights[t];return this.workerNodeVirtualTaskExecutionTime<r?(this.nextWorkerNodeKey=t,this.workerNodeVirtualTaskExecutionTime+=this.getWorkerNodeTaskWaitTime(t)+this.getWorkerNodeTaskRunTime(t)):(this.nextWorkerNodeKey=this.findEligibleWorkerNodeKey(e),this.workerNodeVirtualTaskExecutionTime=0),this.nextWorkerNodeKey}}const ue=()=>{const e=c();let t;e.every(e=>null==e.speed||0===e.speed)&&(t=(()=>{const e=performance.now(),t=performance.now()-e;return Math.trunc(15e7/t/1e3)})());let r=0;for(const s of e){null!=s.speed&&0!==s.speed||(s.speed=e.find(e=>null!=e.speed&&0!==e.speed)?.speed??t??2e3);const i=s.speed.toString().length-1;r+=1/(s.speed/10**i)*10**i}return Math.round(r/e.length)},he=(e,t)=>{t=t??ue();const r={};for(let s=0;s<e;s++)r[s]=t;return r},ke=(e,t)=>((t=structuredClone(t??{})).weights=t.weights??he(e.info.maxSize),{elu:{median:!1},runTime:{median:!1},waitTime:{median:!1},...t}),de=(e,t)=>{e.average&&t&&(e.average=!1,e.median=t),e.median&&!t&&(e.average=!0,e.median=t)},le=e=>{const t=Array.from(e,([e,t])=>t.strategyPolicy);return{dynamicWorkerReady:t.some(e=>e.dynamicWorkerReady),dynamicWorkerUsage:t.some(e=>e.dynamicWorkerUsage)}},ce=e=>{const t=Array.from(e,([e,t])=>t.taskStatisticsRequirements);return{elu:{aggregate:t.some(e=>e.elu.aggregate),average:t.some(e=>e.elu.average),median:t.some(e=>e.elu.median)},runTime:{aggregate:t.some(e=>e.runTime.aggregate),average:t.some(e=>e.runTime.average),median:t.some(e=>e.runTime.median)},waitTime:{aggregate:t.some(e=>e.waitTime.aggregate),average:t.some(e=>e.waitTime.average),median:t.some(e=>e.waitTime.median)}}};class me{pool;defaultWorkerChoiceStrategy;retries;workerChoiceStrategies;workerChoiceStrategiesPolicy;workerChoiceStrategiesTaskStatisticsRequirements;constructor(e,t=[z.LEAST_USED],r){this.pool=e,this.execute=this.execute.bind(this),this.defaultWorkerChoiceStrategy=t[0],this.workerChoiceStrategies=new Map;for(const e of t)this.addWorkerChoiceStrategy(e,this.pool,r);this.workerChoiceStrategiesPolicy=le(this.workerChoiceStrategies),this.workerChoiceStrategiesTaskStatisticsRequirements=ce(this.workerChoiceStrategies),this.retries=((e,t)=>e.info.maxSize+Object.keys(t?.weights??he(e.info.maxSize)).length)(this.pool,r)}execute(e=this.defaultWorkerChoiceStrategy,t){return this.executeStrategy(this.workerChoiceStrategies.get(e),t)}getPolicy(){return this.workerChoiceStrategiesPolicy}getStrategyRetries(){return Array.from(this.workerChoiceStrategies,([e,t])=>t.retriesCount).reduce((e,t)=>e+t,0)}getTaskStatisticsRequirements(){return this.workerChoiceStrategiesTaskStatisticsRequirements}remove(e){return Array.from(this.workerChoiceStrategies,([t,r])=>r.remove(e)).every(e=>e)}setDefaultWorkerChoiceStrategy(e,t){e!==this.defaultWorkerChoiceStrategy&&(this.defaultWorkerChoiceStrategy=e,this.addWorkerChoiceStrategy(e,this.pool,t))}setOptions(e){for(const t of this.workerChoiceStrategies.values())t.setOptions(e)}syncWorkerChoiceStrategies(e,t){for(const t of this.workerChoiceStrategies.keys())e.has(t)||this.removeWorkerChoiceStrategy(t);for(const r of e)this.workerChoiceStrategies.has(r)||this.addWorkerChoiceStrategy(r,this.pool,t);this.workerChoiceStrategiesPolicy=le(this.workerChoiceStrategies),this.workerChoiceStrategiesTaskStatisticsRequirements=ce(this.workerChoiceStrategies)}update(e){return Array.from(this.workerChoiceStrategies,([t,r])=>r.update(e)).every(e=>e)}addWorkerChoiceStrategy(e,t,r){return this.workerChoiceStrategies.has(e)?this.workerChoiceStrategies:this.workerChoiceStrategies.set(e,((e,t,r,s)=>{switch(e){case z.FAIR_SHARE:return new(te.bind(r))(t,s);case z.INTERLEAVED_WEIGHTED_ROUND_ROBIN:return new(re.bind(r))(t,s);case z.LEAST_BUSY:return new(se.bind(r))(t,s);case z.LEAST_ELU:return new(ie.bind(r))(t,s);case z.LEAST_USED:return new(oe.bind(r))(t,s);case z.ROUND_ROBIN:return new(ne.bind(r))(t,s);case z.WEIGHTED_ROUND_ROBIN:return new(ae.bind(r))(t,s);default:throw new Error(`Worker choice strategy '${e}' is not valid`)}})(e,t,this,r))}executeStrategy(e,t){let r=e.choose(t),s=0;for(;null==r&&s<this.retries;)s++,r=e.choose(t);if(e.retriesCount=s,null==r)throw new Error(`Worker node key chosen by ${e.name} is null or undefined after ${e.retriesCount.toString()} retries (max: ${this.retries.toString()})`);return r}removeWorkerChoiceStrategy(e){return this.workerChoiceStrategies.delete(e)}}class ge{size;items;maxArrayIdx;readIdx;writeIdx;constructor(e=2048){this.checkSize(e),this.readIdx=0,this.writeIdx=0,this.maxArrayIdx=e-1,this.size=0,this.items=new Float32Array(e)}clear(){this.readIdx=0,this.writeIdx=0,this.size=0}empty(){return 0===this.size}full(){return this.size===this.items.length}get(){if(this.empty())return;const e=this.items[this.readIdx];return this.readIdx=this.readIdx===this.maxArrayIdx?0:this.readIdx+1,--this.size,e}put(e){this.full()?this.readIdx=this.readIdx===this.maxArrayIdx?0:this.readIdx+1:++this.size,this.items[this.writeIdx]=e,this.writeIdx=this.writeIdx===this.maxArrayIdx?0:this.writeIdx+1}toArray(){if(this.empty())return[];const e=this.size,t=new Array(e);let r=this.readIdx;for(let s=0;s<e;s++)t[s]=this.items[r],r=r===this.maxArrayIdx?0:r+1;return t}checkSize(e){if(!Number.isSafeInteger(e))throw new TypeError(`Invalid circular buffer size: '${e.toString()}' is not an integer`);if(e<=0)throw new RangeError(`Invalid circular buffer size: ${e.toString()} <= 0`)}}class we{capacity;nodeArray;size;start;constructor(e=2048){this.checkSize(e),this.capacity=e,this.nodeArray=new Array(this.capacity),this.clear()}clear(){if(this.size>0){let e=this.start;for(let t=0;t<this.size;t++)this.nodeArray[e]=void 0,++e,e===this.capacity&&(e=0)}this.start=0,this.size=0}delete(e){if(this.empty())return!1;let t=this.start,r=-1;for(let s=0;s<this.size;s++){if(this.nodeArray[t]?.data===e){r=s;break}++t,t===this.capacity&&(t=0)}if(-1!==r){if(r===this.size-1)return this.nodeArray[t]=void 0,--this.size,!0;let e=t;for(let t=r;t<this.size-1;t++){let t=e+1;t===this.capacity&&(t=0),this.nodeArray[e]=this.nodeArray[t],e=t}return this.nodeArray[e]=void 0,--this.size,!0}return!1}dequeue(){if(this.empty())return;const e=this.start,t=this.nodeArray[e].data;return this.nodeArray[e]=void 0,++this.start,this.start===this.capacity&&(this.start=0),--this.size,t}empty(){return 0===this.size}full(){return this.size===this.capacity}get(e){if(!(this.empty()||e<0||e>=this.size))return(e+=this.start)>=this.capacity&&(e-=this.capacity),this.nodeArray[e].data}[Symbol.iterator](){let e=this.start,t=0;return{next:()=>{if(t>=this.size)return{done:!0,value:void 0};const r=this.nodeArray[e].data;return++e,++t,e===this.capacity&&(e=0),{done:!1,value:r}}}}checkSize(e){if(!Number.isSafeInteger(e))throw new TypeError(`Invalid fixed queue size: '${e.toString()}' is not an integer`);if(e<=0)throw new RangeError(`Invalid fixed queue size: ${e.toString()} <= 0`)}}class ye extends we{agingFactor;loadExponent;constructor(e,t=.001,r=1/1.5){super(e),this.agingFactor=t,this.loadExponent=r}enqueue(e,t){if(this.full())throw new Error("Fixed priority queue is full");t=t??0;const r=performance.now(),s=this.agingFactor*(1+((this.size+1)/this.capacity)**this.loadExponent);let i=-1,o=this.start;for(let e=0;e<this.size;e++){const e=this.nodeArray[o];if(e.priority-(r-e.timestamp)*s>t){i=o;break}++o,o===this.capacity&&(o=0)}let n=this.start+this.size;if(n>=this.capacity&&(n-=this.capacity),-1===i)i=n;else{let e=n;for(;e!==i;){const t=0===e?this.capacity-1:e-1;this.nodeArray[e]=this.nodeArray[t],e=t}}return this.nodeArray[i]={data:e,priority:t,timestamp:r},++this.size}}class pe extends we{enqueue(e,t){if(this.full())throw new Error("Fixed queue is full");let r=this.start+this.size;return r>=this.capacity&&(r-=this.capacity),this.nodeArray[r]={data:e,priority:t??0,timestamp:performance.now()},++this.size}}class fe{maxSize;size;get buckets(){return Math.trunc(this.size/this.bucketSize)}get enablePriority(){return this.priorityEnabled}set enablePriority(e){if(this.priorityEnabled===e)return;this.priorityEnabled=e;const t=Array.from(this);this.clear();for(const e of t)this.enqueue(e)}agingFactor;bucketSize;head;loadExponent;priorityEnabled;tail;constructor(e=2048,t=!1,r,s){if(!Number.isSafeInteger(e))throw new TypeError(`Invalid bucket size: '${e.toString()}' is not an integer`);if(e<=0)throw new RangeError(`Invalid bucket size: ${e.toString()} <= 0`);this.bucketSize=e,this.priorityEnabled=t,this.agingFactor=r??.001,this.loadExponent=s??N,this.clear()}clear(){this.head=this.tail=this.getPriorityQueueNode(),this.size=0,this.maxSize=0}delete(e){if(0===this.size)return!1;let t,r=this.tail;for(;null!=r;){if(r.delete(e))return r.empty()&&this.removePriorityQueueNode(r,t),--this.size,!0;t=r,r=r.next}return!1}dequeue(e){if(0===this.size)return;let t,r=this.tail;if(null!=e&&e>0){let s=1;for(;null!=r.next&&s<e;)t=r,r=r.next,++s;if(s<e||r.empty())return}else for(;!0===r?.empty()&&r!==this.head;)t=r,r=r.next;if(null==r||r.empty())return;const s=r.dequeue();return--this.size,r.empty()&&this.removePriorityQueueNode(r,t),s}enqueue(e,t){return this.head.full()&&(this.head=this.head.next=this.getPriorityQueueNode()),this.head.enqueue(e,t),++this.size,this.size>this.maxSize&&(this.maxSize=this.size),this.size}[Symbol.iterator](){let e=this.tail,t=0;return{next:()=>{for(;;){if(null==e)return{done:!0,value:void 0};for(;t>=e.size;)if(e=e.next,t=0,null==e)return{done:!0,value:void 0};const r=e.get(t);if(++t,null!=r)return{done:!1,value:r}}}}}getPriorityQueueNode(){let e;return e=this.priorityEnabled?new ye(this.bucketSize,this.agingFactor,this.loadExponent):new pe(this.bucketSize),e}removePriorityQueueNode(e,t){this.head!==this.tail&&(e===this.tail&&null!=e.next?this.tail=e.next:e===this.head&&null!=t?(this.head=t,this.head.next=void 0):null!=t&&(t.next=e.next),e.next=void 0)}}class Ne extends g{info;messageChannel;strategyData;tasksQueue;tasksQueueBackPressureSize;usage;worker;taskFunctionsUsage;constructor(t,r,s){var a;super(),((e,t,r)=>{if(null==e)throw new TypeError("Cannot construct a worker node without a worker type");if(!Object.values(q).includes(e))throw new TypeError(`Cannot construct a worker node with an invalid worker type '${e}'`);if(D(t),null==r)throw new TypeError("Cannot construct a worker node without worker node options");if(!x(r))throw new TypeError("Cannot construct a worker node with invalid worker node options: must be a plain object");if(null==r.tasksQueueBackPressureSize)throw new TypeError("Cannot construct a worker node without a tasks queue back pressure size option");if(!Number.isSafeInteger(r.tasksQueueBackPressureSize))throw new TypeError("Cannot construct a worker node with a tasks queue back pressure size option that is not an integer");if(r.tasksQueueBackPressureSize<=0)throw new RangeError("Cannot construct a worker node with a tasks queue back pressure size option that is not a positive integer");if(null==r.tasksQueueBucketSize)throw new TypeError("Cannot construct a worker node without a tasks queue bucket size option");if(!Number.isSafeInteger(r.tasksQueueBucketSize))throw new TypeError("Cannot construct a worker node with a tasks queue bucket size option that is not an integer");if(r.tasksQueueBucketSize<=0)throw new RangeError("Cannot construct a worker node with a tasks queue bucket size option that is not a positive integer");if(null==r.tasksQueuePriority)throw new TypeError("Cannot construct a worker node without a tasks queue priority option");if("boolean"!=typeof r.tasksQueuePriority)throw new TypeError("Cannot construct a worker node with a tasks queue priority option that is not a boolean")})(t,r,s),this.worker=((t,r,s)=>{switch(t){case q.cluster:return e.fork(s.env);case q.thread:return new i(r,{env:o,...s.workerOptions});default:throw new Error(`Unknown worker type '${t}'`)}})(t,r,{env:s.env,workerOptions:s.workerOptions}),this.info=(a=this.worker,{backPressure:!1,backPressureStealing:!1,continuousStealing:!1,dynamic:!1,id:X(a),queuedTaskAbortion:!1,ready:!1,stealing:!1,stolen:!1,type:J(a)}),this.usage=this.initWorkerUsage(),this.info.type===q.thread&&(this.messageChannel=new n),this.tasksQueueBackPressureSize=s.tasksQueueBackPressureSize,this.tasksQueue=new fe(s.tasksQueueBucketSize,s.tasksQueuePriority,s.tasksQueueAgingFactor,s.tasksQueueLoadExponent),this.taskFunctionsUsage=new Map}clearTasksQueue(){this.tasksQueue.clear()}deleteTask(e){return this.tasksQueue.delete(e)}deleteTaskFunctionWorkerUsage(e){return this.taskFunctionsUsage.delete(e)}dequeueLastPrioritizedTask(){return this.dequeueTask(this.tasksQueue.buckets+1)}dequeueTask(e){const t=this.tasksQueue.dequeue(e);return!this.hasBackPressure()&&this.info.backPressure&&(this.info.backPressure=!1),t}enqueueTask(e){const t=this.tasksQueue.enqueue(e,e.priority);return this.hasBackPressure()&&!this.info.backPressure&&(this.info.backPressure=!0,this.emit("backPressure",{workerId:this.info.id})),t}getTaskFunctionWorkerUsage(e){if(!Array.isArray(this.info.taskFunctionsProperties))throw new Error(`Cannot get task function worker usage for task function name '${e}' when task function properties list is not yet defined`);if(Array.isArray(this.info.taskFunctionsProperties)&&this.info.taskFunctionsProperties.length<3)throw new Error(`Cannot get task function worker usage for task function name '${e}' when task function properties list has less than 3 elements`);return e===T&&(e=this.info.taskFunctionsProperties[1].name),this.taskFunctionsUsage.has(e)||this.taskFunctionsUsage.set(e,this.initTaskFunctionWorkerUsage(e)),this.taskFunctionsUsage.get(e)}registerOnceWorkerEventHandler(e,t){this.worker.once(e,t)}registerWorkerEventHandler(e,t){this.worker.on(e,t)}setTasksQueuePriority(e){this.tasksQueue.enablePriority=e}tasksQueueSize(){return this.tasksQueue.size}async terminate(){const e=new Promise(e=>{this.registerOnceWorkerEventHandler("exit",()=>{e()})});switch(this.closeMessageChannel(),this.removeAllListeners(),this.info.type){case q.cluster:this.registerOnceWorkerEventHandler("disconnect",()=>{this.worker.kill?.()}),this.worker.disconnect?.();break;case q.thread:this.worker.unref?.(),await(this.worker.terminate?.())}await e,this.worker.removeAllListeners()}closeMessageChannel(){null!=this.messageChannel&&(this.messageChannel.port1.unref(),this.messageChannel.port2.unref(),this.messageChannel.port1.close(),this.messageChannel.port2.close(),delete this.messageChannel)}hasBackPressure(){return this.tasksQueue.size>=this.tasksQueueBackPressureSize}initTaskFunctionWorkerUsage(e){const t=()=>{let t=0;for(const r of this.tasksQueue)(r.name===T&&e===this.info.taskFunctionsProperties[1].name||r.name!==T&&e===r.name)&&++t;return t};return{elu:{active:{history:new ge(K)},idle:{history:new ge(K)}},runTime:{history:new ge(K)},tasks:{executed:0,executing:0,failed:0,get queued(){return t()},sequentiallyStolen:0,stolen:0},waitTime:{history:new ge(K)}}}initWorkerUsage(){const e=()=>this.tasksQueue.size,t=()=>this.tasksQueue.maxSize;return{elu:{active:{history:new ge(K)},idle:{history:new ge(K)}},runTime:{history:new ge(K)},tasks:{executed:0,executing:0,failed:0,get maxQueued(){return t()},get queued(){return e()},sequentiallyStolen:0,stolen:0},waitTime:{history:new ge(K)}}}}class Te{minimumNumberOfWorkers;filePath;opts;maximumNumberOfWorkers;emitter;workerNodes=[];get info(){const e=this.workerChoiceStrategiesContext?.getTaskStatisticsRequirements();return{defaultStrategy:this.opts.workerChoiceStrategy,maxSize:this.maximumNumberOfWorkers??this.minimumNumberOfWorkers,minSize:this.minimumNumberOfWorkers,ready:this.ready,started:this.started,strategyRetries:this.workerChoiceStrategiesContext?.getStrategyRetries()??0,type:this.type,version:"5.3.0",worker:this.worker,...!0===e?.runTime.aggregate&&e.waitTime.aggregate&&{utilization:v(this.utilization)},busyWorkerNodes:this.workerNodes.reduce((e,t,r)=>this.isWorkerNodeBusy(r)?e+1:e,0),executedTasks:this.workerNodes.reduce((e,t)=>e+t.usage.tasks.executed,0),executingTasks:this.workerNodes.reduce((e,t)=>e+t.usage.tasks.executing,0),failedTasks:this.workerNodes.reduce((e,t)=>e+t.usage.tasks.failed,0),idleWorkerNodes:this.workerNodes.reduce((e,t,r)=>this.isWorkerNodeIdle(r)?e+1:e,0),workerNodes:this.workerNodes.length,...this.type===p.dynamic&&{dynamicWorkerNodes:this.workerNodes.reduce((e,t)=>t.info.dynamic?e+1:e,0)},...!0===this.opts.enableTasksQueue&&{backPressure:this.backPressure,backPressureWorkerNodes:this.workerNodes.reduce((e,t,r)=>this.isWorkerNodeBackPressured(r)?e+1:e,0),maxQueuedTasks:this.workerNodes.reduce((e,t)=>e+(t.usage.tasks.maxQueued??0),0),queuedTasks:this.getQueuedTasks(),stealingWorkerNodes:this.getStealingWorkerNodes(),stolenTasks:this.workerNodes.reduce((e,t)=>e+t.usage.tasks.stolen,0)},...!0===e?.runTime.aggregate&&{runTime:{maximum:v(P(...this.workerNodes.map(e=>e.usage.runTime.maximum??Number.NEGATIVE_INFINITY))),minimum:v(C(...this.workerNodes.map(e=>e.usage.runTime.minimum??Number.POSITIVE_INFINITY))),...e.runTime.average&&{average:v(S(this.workerNodes.reduce((e,t)=>e.concat(t.usage.runTime.history.toArray()),[])))},...e.runTime.median&&{median:v(b(this.workerNodes.reduce((e,t)=>e.concat(t.usage.runTime.history.toArray()),[])))}}},...!0===e?.waitTime.aggregate&&{waitTime:{maximum:v(P(...this.workerNodes.map(e=>e.usage.waitTime.maximum??Number.NEGATIVE_INFINITY))),minimum:v(C(...this.workerNodes.map(e=>e.usage.waitTime.minimum??Number.POSITIVE_INFINITY))),...e.waitTime.average&&{average:v(S(this.workerNodes.reduce((e,t)=>e.concat(t.usage.waitTime.history.toArray()),[])))},...e.waitTime.median&&{median:v(b(this.workerNodes.reduce((e,t)=>e.concat(t.usage.waitTime.history.toArray()),[])))}}},...!0===e?.elu.aggregate&&{elu:{active:{maximum:v(P(...this.workerNodes.map(e=>e.usage.elu.active.maximum??Number.NEGATIVE_INFINITY))),minimum:v(C(...this.workerNodes.map(e=>e.usage.elu.active.minimum??Number.POSITIVE_INFINITY))),...e.elu.average&&{average:v(S(this.workerNodes.reduce((e,t)=>e.concat(t.usage.elu.active.history.toArray()),[])))},...e.elu.median&&{median:v(b(this.workerNodes.reduce((e,t)=>e.concat(t.usage.elu.active.history.toArray()),[])))}},idle:{maximum:v(P(...this.workerNodes.map(e=>e.usage.elu.idle.maximum??Number.NEGATIVE_INFINITY))),minimum:v(C(...this.workerNodes.map(e=>e.usage.elu.idle.minimum??Number.POSITIVE_INFINITY))),...e.elu.average&&{average:v(S(this.workerNodes.reduce((e,t)=>e.concat(t.usage.elu.idle.history.toArray()),[])))},...e.elu.median&&{median:v(b(this.workerNodes.reduce((e,t)=>e.concat(t.usage.elu.idle.history.toArray()),[])))}},utilization:{average:v(S(this.workerNodes.map(e=>e.usage.elu.utilization??0))),median:v(b(this.workerNodes.map(e=>e.usage.elu.utilization??0)))}}}}}destroying;promiseResponseMap=new Map;started;starting;workerChoiceStrategiesContext;backPressureEventEmitted;busyEventEmitted;readyEventEmitted;startingMinimumNumberOfWorkers;startTimestamp;taskFunctions;get ready(){return!!this.started&&this.workerNodes.reduce((e,t)=>!t.info.dynamic&&t.info.ready?e+1:e,0)>=this.minimumNumberOfWorkers}get utilization(){if(null==this.startTimestamp)return 0;const e=(y.now()-this.startTimestamp)*(this.maximumNumberOfWorkers??this.minimumNumberOfWorkers);if(!Number.isFinite(e)||e<=0)return 0;return(this.workerNodes.reduce((e,t)=>e+(t.usage.runTime.aggregate??0),0)+this.workerNodes.reduce((e,t)=>e+(t.usage.waitTime.aggregate??0),0))/e}constructor(e,t,r,s){if(this.minimumNumberOfWorkers=e,this.filePath=t,this.opts=r,this.maximumNumberOfWorkers=s,!this.isMain())throw new Error("Cannot start a pool from a worker with the same type as the pool");this.checkPoolType(),D(this.filePath),this.checkMinimumNumberOfWorkers(this.minimumNumberOfWorkers),this.checkPoolOptions(this.opts),this.chooseWorkerNode=this.chooseWorkerNode.bind(this),this.executeTask=this.executeTask.bind(this),this.enqueueTask=this.enqueueTask.bind(this),!0===this.opts.enableEvents&&this.initEventEmitter(),this.workerChoiceStrategiesContext=new me(this,[this.opts.workerChoiceStrategy],this.opts.workerChoiceStrategyOptions),this.setupHook(),this.taskFunctions=new Map,this.started=!1,this.starting=!1,this.destroying=!1,this.readyEventEmitted=!1,this.busyEventEmitted=!1,this.backPressureEventEmitted=!1,this.startingMinimumNumberOfWorkers=!1,!0===this.opts.startWorkers&&this.start()}async addTaskFunction(e,t){if("string"!=typeof e)throw new TypeError("name argument must be a string");if("string"==typeof e&&0===e.trim().length)throw new TypeError("name argument must not be an empty string");if("function"==typeof t&&(t={taskFunction:t}),"function"!=typeof t.taskFunction)throw new TypeError("taskFunction property must be a function");B(t.priority),_(t.strategy),L(t.workerNodeKeys,this.maximumNumberOfWorkers??this.minimumNumberOfWorkers);const r=await this.sendTaskFunctionOperationToWorkers({taskFunction:t.taskFunction.toString(),taskFunctionOperation:"add",taskFunctionProperties:A(e,t)});this.taskFunctions.set(e,t),this.workerChoiceStrategiesContext?.syncWorkerChoiceStrategies(this.getWorkerChoiceStrategies());for(const e of this.workerNodes.keys())this.sendStatisticsMessageToWorker(e);return r}async destroy(){if(!this.started)throw new Error("Cannot destroy an already destroyed pool");if(this.starting)throw new Error("Cannot destroy an starting pool");if(this.destroying)throw new Error("Cannot destroy an already destroying pool");this.destroying=!0;try{await Promise.allSettled(this.workerNodes.map(async(e,t)=>{try{await this.destroyWorkerNode(t)}catch(e){this.emitter?.emit(f.error,e)}}))}finally{delete this.startTimestamp,this.destroying=!1,this.started=!1,null!=this.emitter&&(this.emitter.listenerCount(f.destroy)>0&&this.emitter.emit(f.destroy,this.info),this.emitter.emitDestroy(),this.readyEventEmitted=!1)}}enableTasksQueue(e,t){!0!==this.opts.enableTasksQueue||e||(this.unsetTaskStealing(),this.unsetTasksStealingOnBackPressure(),this.flushTasksQueues()),this.opts.enableTasksQueue=e,this.setTasksQueueOptions(t)}async execute(e,t,r,s){if(!this.started)throw new Error("Cannot execute a task on not started pool");if(this.destroying)throw new Error("Cannot execute a task on destroying pool");if(null!=t&&"string"!=typeof t)throw new TypeError("name argument must be a string");if(null!=t&&"string"==typeof t&&0===t.trim().length)throw new TypeError("name argument must not be an empty string");if(null!=r&&!(r instanceof AbortSignal))throw new TypeError("abortSignal argument must be an AbortSignal");if(null!=s&&!Array.isArray(s))throw new TypeError("transferList argument must be an array");return await this.internalExecute(e,t,r,s)}hasTaskFunction(e){return this.listTaskFunctionsProperties().some(t=>t.name===e)}listTaskFunctionsProperties(){for(const e of this.workerNodes)if(Array.isArray(e.info.taskFunctionsProperties)&&e.info.taskFunctionsProperties.length>0)return e.info.taskFunctionsProperties;return[]}async mapExecute(e,t,r,s){if(!this.started)throw new Error("Cannot execute task(s) on not started pool");if(this.destroying)throw new Error("Cannot execute task(s) on destroying pool");if(null==e)throw new TypeError("data argument must be a defined iterable");if("function"!=typeof e[Symbol.iterator])throw new TypeError("data argument must be an iterable");if(null!=t&&"string"!=typeof t)throw new TypeError("name argument must be a string");if(null!=t&&"string"==typeof t&&0===t.trim().length)throw new TypeError("name argument must not be an empty string");if(Array.isArray(e)||(e=[...e]),null!=r){if("function"!=typeof r[Symbol.iterator])throw new TypeError("abortSignals argument must be an iterable");for(const e of r)if(!(e instanceof AbortSignal))throw new TypeError("abortSignals argument must be an iterable of AbortSignal");if(Array.isArray(r)||(r=[...r]),e.length!==r.length)throw new Error("data and abortSignals arguments must have the same length")}if(null!=s&&!Array.isArray(s))throw new TypeError("transferList argument must be an array");const i=Array.from({length:e.length},(t,s)=>[e[s],null!=r?r[s]:void 0]);return await Promise.all(i.map(([e,r])=>this.internalExecute(e,t,r,s)))}async removeTaskFunction(e){if(!this.taskFunctions.has(e))throw new Error("Cannot remove a task function not handled on the pool side");const t=await this.sendTaskFunctionOperationToWorkers({taskFunctionOperation:"remove",taskFunctionProperties:A(e,this.taskFunctions.get(e))});for(const t of this.workerNodes)t.deleteTaskFunctionWorkerUsage(e);this.taskFunctions.delete(e),this.workerChoiceStrategiesContext?.syncWorkerChoiceStrategies(this.getWorkerChoiceStrategies());for(const e of this.workerNodes.keys())this.sendStatisticsMessageToWorker(e);return t}async setDefaultTaskFunction(e){return await this.sendTaskFunctionOperationToWorkers({taskFunctionOperation:"default",taskFunctionProperties:A(e,this.taskFunctions.get(e))})}setTasksQueueOptions(e){!0===this.opts.enableTasksQueue?($(e),this.opts.tasksQueueOptions=this.buildTasksQueueOptions(e),this.setTasksQueueSize(this.opts.tasksQueueOptions.size),!0===this.opts.tasksQueueOptions.taskStealing?(this.unsetTaskStealing(),this.setTaskStealing()):this.unsetTaskStealing(),!0===this.opts.tasksQueueOptions.tasksStealingOnBackPressure?(this.unsetTasksStealingOnBackPressure(),this.setTasksStealingOnBackPressure()):this.unsetTasksStealingOnBackPressure()):null!=this.opts.tasksQueueOptions&&delete this.opts.tasksQueueOptions}setWorkerChoiceStrategy(e,t){let r=!1;if(_(e),null!=t&&(r=!this.setWorkerChoiceStrategyOptions(t)),e!==this.opts.workerChoiceStrategy&&(this.opts.workerChoiceStrategy=e,this.workerChoiceStrategiesContext?.setDefaultWorkerChoiceStrategy(this.opts.workerChoiceStrategy,this.opts.workerChoiceStrategyOptions),r=!0),r){this.workerChoiceStrategiesContext?.syncWorkerChoiceStrategies(this.getWorkerChoiceStrategies(),this.opts.workerChoiceStrategyOptions);for(const e of this.workerNodes.keys())this.sendStatisticsMessageToWorker(e)}}setWorkerChoiceStrategyOptions(e){if(this.checkValidWorkerChoiceStrategyOptions(e),null!=e){this.opts.workerChoiceStrategyOptions={...this.opts.workerChoiceStrategyOptions,...e},this.workerChoiceStrategiesContext?.setOptions(this.opts.workerChoiceStrategyOptions),this.workerChoiceStrategiesContext?.syncWorkerChoiceStrategies(this.getWorkerChoiceStrategies(),this.opts.workerChoiceStrategyOptions);for(const e of this.workerNodes.keys())this.sendStatisticsMessageToWorker(e);return!0}return!1}start(){if(this.started)throw new Error("Cannot start an already started pool");if(this.starting)throw new Error("Cannot start an already starting pool");if(this.destroying)throw new Error("Cannot start a destroying pool");this.starting=!0,this.startMinimumNumberOfWorkers(),this.startTimestamp=y.now(),this.starting=!1,this.started=!0}afterTaskExecutionHook(e,t){let r=!1;if(null!=this.workerNodes[e]?.usage){const s=this.workerNodes[e].usage;j(s,t),Y(this.workerChoiceStrategiesContext,s,t),G(this.workerChoiceStrategiesContext,s,t),r=!0}if(this.shallUpdateTaskFunctionWorkerUsage(e)&&null!=t.taskPerformance?.name&&null!=this.workerNodes[e].getTaskFunctionWorkerUsage(t.taskPerformance.name)){const s=this.workerNodes[e].getTaskFunctionWorkerUsage(t.taskPerformance.name);j(s,t),Y(this.workerChoiceStrategiesContext,s,t),G(this.workerChoiceStrategiesContext,s,t),r=!0}r&&this.workerChoiceStrategiesContext?.update(e)}afterWorkerNodeSetup(e){this.registerWorkerMessageListener(e,this.workerMessageListener),this.sendStartupMessageToWorker(e),this.sendStatisticsMessageToWorker(e),!0===this.opts.enableTasksQueue&&(!0===this.opts.tasksQueueOptions?.taskStealing&&this.workerNodes[e].on("idle",this.handleWorkerNodeIdleEvent),!0===this.opts.tasksQueueOptions?.tasksStealingOnBackPressure&&this.workerNodes[e].on("backPressure",this.handleWorkerNodeBackPressureEvent)),this.workerNodes[e].on("abortTask",this.abortTask)}beforeTaskExecutionHook(e,t){if(null!=this.workerNodes[e]?.usage){const r=this.workerNodes[e].usage;++r.tasks.executing,H(this.workerChoiceStrategiesContext,r,t)}if(this.shallUpdateTaskFunctionWorkerUsage(e)&&null!=this.workerNodes[e].getTaskFunctionWorkerUsage(t.name)){const r=this.workerNodes[e].getTaskFunctionWorkerUsage(t.name);++r.tasks.executing,H(this.workerChoiceStrategiesContext,r,t)}}createAndSetupDynamicWorkerNode(){const e=this.createAndSetupWorkerNode();if(this.registerWorkerMessageListener(e,e=>{if(this.destroying)return;this.checkMessageWorkerId(e);const t=this.getWorkerNodeKeyByWorkerId(e.workerId);(I(Z.HARD,e.kill)||I(Z.SOFT,e.kill)&&this.isWorkerNodeIdle(t)&&!this.isWorkerNodeStealing(t))&&this.destroyWorkerNode(t).catch(e=>{this.emitter?.emit(f.error,e)})}),this.sendToWorker(e,{checkActive:!0}),this.taskFunctions.size>0)for(const[t,r]of this.taskFunctions)this.sendTaskFunctionOperationToWorker(e,{taskFunction:r.taskFunction.toString(),taskFunctionOperation:"add",taskFunctionProperties:A(t,r)}).catch(e=>{this.emitter?.emit(f.error,e)});const t=this.workerNodes[e];return t.info.dynamic=!0,!0===this.workerChoiceStrategiesContext?.getPolicy().dynamicWorkerReady&&(t.info.ready=!0),this.initWorkerNodeUsage(t),this.checkAndEmitDynamicWorkerCreationEvents(),e}createAndSetupWorkerNode(){const e=this.createWorkerNode();e.registerWorkerEventHandler("online",this.opts.onlineHandler??W),e.registerWorkerEventHandler("message",this.opts.messageHandler??W),e.registerWorkerEventHandler("error",this.opts.errorHandler??W),e.registerOnceWorkerEventHandler("error",t=>{e.info.ready=!1,this.emitter?.emit(f.error,t),this.started&&!this.destroying&&(!0===this.opts.restartWorkerOnError&&(e.info.dynamic?this.createAndSetupDynamicWorkerNode():this.startingMinimumNumberOfWorkers||this.startMinimumNumberOfWorkers(!0)),!0===this.opts.enableTasksQueue&&this.redistributeQueuedTasks(this.workerNodes.indexOf(e))),e?.terminate().catch(e=>{this.emitter?.emit(f.error,e)})}),e.registerWorkerEventHandler("exit",this.opts.exitHandler??W),e.registerOnceWorkerEventHandler("exit",()=>{this.removeWorkerNode(e),!this.started||this.startingMinimumNumberOfWorkers||this.destroying||this.startMinimumNumberOfWorkers(!0)});const t=this.addWorkerNode(e);return this.afterWorkerNodeSetup(t),t}async destroyWorkerNode(e){this.flagWorkerNodeAsNotReady(e);const t=this.flushTasksQueue(e),r=this.workerNodes[e];await(async(e,t,r,s,i=!0)=>await new Promise((o,n)=>{let a=0;if(0===r)return void o(a);const u=()=>{++a,a>=r&&(null!=h&&clearTimeout(h),e.off(t,u),o(a))},h=s>=0?setTimeout(()=>{e.off(t,u),i?n(new Error(`Timed out after ${s.toString()}ms waiting for ${r.toString()} '${t}' events. Received ${a.toString()} events`)):o(a)},s):void 0;switch(t){case"backPressure":case"idle":case"taskFinished":e.on(t,u);break;default:null!=h&&clearTimeout(h),n(new Error("Invalid worker node event"))}}))(r,"taskFinished",t,this.opts.tasksQueueOptions?.tasksFinishedTimeout??Q(this.maximumNumberOfWorkers??this.minimumNumberOfWorkers).tasksFinishedTimeout,!1),await this.sendKillMessageToWorker(e),await r.terminate()}flagWorkerNodeAsNotReady(e){const t=this.getWorkerInfo(e);null!=t&&(t.ready=!1)}flushTasksQueue(e){let t=0;for(;this.tasksQueueSize(e)>0;)this.executeTask(e,this.dequeueTask(e)),++t;return this.workerNodes[e].clearTasksQueue(),t}getWorkerInfo(e){return this.workerNodes[e]?.info}internalBackPressure(){return 0!==this.workerNodes.length&&this.workerNodes.reduce((e,t,r)=>this.isWorkerNodeBackPressured(r)?e+1:e,0)===this.workerNodes.length}internalBusy(){return 0!==this.workerNodes.length&&this.workerNodes.reduce((e,t,r)=>this.isWorkerNodeBusy(r)?e+1:e,0)===this.workerNodes.length}setupHook(){}workerMessageListener=e=>{const{kill:t,ready:r,taskFunctionsProperties:s,taskId:i,workerId:o}=e,n=null!=r&&null!=s;if(!(this.destroying&&n||null!=t))if(this.checkMessageWorkerId(e),n)this.handleWorkerReadyResponse(e);else if(null!=s){const e=this.getWorkerNodeKeyByWorkerId(o),t=this.getWorkerInfo(e);null!=t&&(t.taskFunctionsProperties=s,this.sendStatisticsMessageToWorker(e),this.setTasksQueuePriority(e))}else null!=i&&this.handleTaskExecutionResponse(e)};abortTask=e=>{if(!this.started)return;const{taskId:t,workerId:r}=e,s=this.promiseResponseMap.get(t);if(null==s)return;const{abortSignal:i,reject:o}=s;if(!1===i?.aborted)return;const n=this.getWorkerNodeKeyByWorkerId(r),a=this.workerNodes[n];if(a.info.ready){if(!0===this.opts.enableTasksQueue)for(const e of a.tasksQueue){const{abortable:r,name:s}=e;if(t===e.taskId&&!0===r)return a.info.queuedTaskAbortion=!0,a.deleteTask(e),this.promiseResponseMap.delete(t),a.info.queuedTaskAbortion=!1,void o(this.getAbortError(s,t))}this.sendToWorker(n,{taskId:t,taskOperation:"abort"})}};addWorkerNode(e){this.workerNodes.push(e);const t=this.workerNodes.indexOf(e);if(-1===t)throw new Error("Worker added not found in worker nodes");return t}buildTasksQueueOptions(e){return{...Q(this.maximumNumberOfWorkers??this.minimumNumberOfWorkers),...this.opts.tasksQueueOptions,...e}}cannotStealTask(){return!this.started||this.destroying||this.workerNodes.length<=1||0===this.getQueuedTasks()}checkAndEmitReadyEvent(){null!=this.emitter&&!this.readyEventEmitted&&this.ready&&(this.emitter.listenerCount(f.ready)>0&&this.emitter.emit(f.ready,this.info),this.readyEventEmitted=!0)}checkAndEmitTaskDequeuingEvents(){null!=this.emitter&&this.backPressureEventEmitted&&!this.backPressure&&(this.emitter.listenerCount(f.backPressureEnd)>0&&this.emitter.emit(f.backPressureEnd,this.info),this.backPressureEventEmitted=!1)}checkAndEmitTaskExecutionEvents(){null!=this.emitter&&!this.busyEventEmitted&&this.busy&&(this.emitter.listenerCount(f.busy)>0&&this.emitter.emit(f.busy,this.info),this.busyEventEmitted=!0)}checkAndEmitTaskExecutionFinishedEvents(){null!=this.emitter&&this.busyEventEmitted&&!this.busy&&(this.emitter.listenerCount(f.busyEnd)>0&&this.emitter.emit(f.busyEnd,this.info),this.busyEventEmitted=!1)}checkAndEmitTaskQueuingEvents(){null!=this.emitter&&!this.backPressureEventEmitted&&this.backPressure&&(this.emitter.listenerCount(f.backPressure)>0&&this.emitter.emit(f.backPressure,this.info),this.backPressureEventEmitted=!0)}checkMessageWorkerId(e){if(null==e.workerId)throw new Error(`Worker message '${JSON.stringify(e)}' received without worker id`);if(-1===this.getWorkerNodeKeyByWorkerId(e.workerId))throw new Error(`Worker message '${JSON.stringify(e)}' received from unknown worker ${e.workerId.toString()}`)}checkMinimumNumberOfWorkers(e){if(null==e)throw new Error("Cannot instantiate a pool without specifying the number of workers");if(!Number.isSafeInteger(e))throw new TypeError("Cannot instantiate a pool with a non safe integer number of workers");if(e<0)throw new RangeError("Cannot instantiate a pool with a negative number of workers");if(this.type===p.fixed&&0===e)throw new RangeError("Cannot instantiate a fixed pool with zero worker")}checkPoolOptions(e){if(!x(e))throw new TypeError("Invalid pool options: must be a plain object");this.opts.startWorkers=e.startWorkers??!0,_(e.workerChoiceStrategy),this.opts.workerChoiceStrategy=e.workerChoiceStrategy??z.LEAST_USED,this.checkValidWorkerChoiceStrategyOptions(e.workerChoiceStrategyOptions),null!=e.workerChoiceStrategyOptions&&(this.opts.workerChoiceStrategyOptions=e.workerChoiceStrategyOptions),this.opts.restartWorkerOnError=e.restartWorkerOnError??!0,this.opts.enableEvents=e.enableEvents??!0,this.opts.enableTasksQueue=e.enableTasksQueue??!1,this.opts.enableTasksQueue&&($(e.tasksQueueOptions),this.opts.tasksQueueOptions=this.buildTasksQueueOptions(e.tasksQueueOptions))}checkPoolType(){if(this.type===p.fixed&&null!=this.maximumNumberOfWorkers)throw new Error("Cannot instantiate a fixed pool with a maximum number of workers defined at initialization")}checkValidWorkerChoiceStrategyOptions(e){if(null!=e&&!x(e))throw new TypeError("Invalid worker choice strategy options: must be a plain object");if(null!=e?.weights&&Object.keys(e.weights).length!==(this.maximumNumberOfWorkers??this.minimumNumberOfWorkers))throw new Error("Invalid worker choice strategy options: must have a weight for each worker node");if(null!=e?.measurement&&!Object.values(R).includes(e.measurement))throw new Error(`Invalid worker choice strategy options: invalid measurement '${e.measurement}'`)}chooseWorkerNode(e){const t=this.getTaskFunctionWorkerNodeKeysSet(e);if(null!=t){const e=this.maximumNumberOfWorkers??this.minimumNumberOfWorkers,r=P(...t)+1;for(;this.started&&!this.destroying&&this.workerNodes.length<r&&this.workerNodes.length<e;)this.createAndSetupDynamicWorkerNode()}else if(this.shallCreateDynamicWorker()){const e=this.createAndSetupDynamicWorkerNode();if(!0===this.workerChoiceStrategiesContext?.getPolicy().dynamicWorkerUsage)return e}return this.workerChoiceStrategiesContext.execute(this.getTaskFunctionWorkerChoiceStrategy(e),t)}createWorkerNode(){const e=new Ne(this.worker,this.filePath,{env:this.opts.env,tasksQueueAgingFactor:this.opts.tasksQueueOptions?.agingFactor,tasksQueueBackPressureSize:this.opts.tasksQueueOptions?.size??Q(this.maximumNumberOfWorkers??this.minimumNumberOfWorkers).size,tasksQueueBucketSize:2048,tasksQueueLoadExponent:this.opts.tasksQueueOptions?.loadExponent,tasksQueuePriority:this.getTasksQueuePriority(),workerOptions:this.opts.workerOptions});return this.starting&&(e.info.ready=!0),e}dequeueTask(e){const t=this.workerNodes[e].dequeueTask();return this.checkAndEmitTaskDequeuingEvents(),t}enqueueTask(e,t){const r=this.workerNodes[e].enqueueTask(t);return this.checkAndEmitTaskQueuingEvents(),r}executeTask(e,t){const{transferList:r}=t;this.beforeTaskExecutionHook(e,t),this.sendToWorker(e,t,r),this.checkAndEmitTaskExecutionEvents()}flushTasksQueues(){for(const e of this.workerNodes.keys())this.flushTasksQueue(e)}getAbortError=(e,t)=>{const r=this.promiseResponseMap.get(t)?.abortSignal?.reason;return r instanceof Error?r:"string"==typeof r?new Error(r):new Error(`Task '${e}' id '${t}' aborted`)};getQueuedTasks(){return this.workerNodes.reduce((e,t)=>e+t.usage.tasks.queued,0)}getStealingWorkerNodes(){return this.workerNodes.reduce((e,t,r)=>this.isWorkerNodeStealing(r)?e+1:e,0)}getTaskFunctionWorkerChoiceStrategy=e=>{e=e??T;const t=this.listTaskFunctionsProperties();return e===T&&(e=t[1]?.name),t.find(t=>t.name===e)?.strategy};getTaskFunctionWorkerNodeKeysSet=e=>{e=e??T;const t=this.listTaskFunctionsProperties();e===T&&(e=t[1]?.name);const r=t.find(t=>t.name===e)?.workerNodeKeys;return null!=r?new Set(r):void 0};getTasksQueuePriority(){return this.listTaskFunctionsProperties().some(e=>null!=e.priority)}getWorkerChoiceStrategies=()=>new Set([this.opts.workerChoiceStrategy,...this.listTaskFunctionsProperties().map(e=>e.strategy).filter(e=>null!=e)]);getWorkerNodeKeyByWorkerId(e){return this.workerNodes.findIndex(t=>t.info.id===e)}getWorkerNodeTaskFunctionPriority=(e,t)=>{const r=this.getWorkerInfo(e);if(null!=r)return(t=t??T)===T&&(t=r.taskFunctionsProperties?.[1]?.name),r.taskFunctionsProperties?.find(e=>e.name===t)?.priority};getWorkerNodeTaskFunctionWorkerChoiceStrategy=(e,t)=>{const r=this.getWorkerInfo(e);if(null!=r)return(t=t??T)===T&&(t=r.taskFunctionsProperties?.[1]?.name),r.taskFunctionsProperties?.find(e=>e.name===t)?.strategy};handleTask(e,t){this.shallExecuteTask(e)?this.executeTask(e,t):this.enqueueTask(e,t)}handleTaskExecutionResponse(e){const{data:t,taskId:r,workerError:s}=e,i=this.promiseResponseMap.get(r);if(null!=i){const{asyncResource:o,reject:n,resolve:a,workerNodeKey:u}=i,h=this.workerNodes[u];if(null!=s){this.emitter?.emit(f.taskError,s);const e=this.handleWorkerError(r,s);null!=o?o.runInAsyncScope(n,this.emitter,e):n(e)}else null!=o?o.runInAsyncScope(a,this.emitter,t):a(t);o?.emitDestroy(),this.afterTaskExecutionHook(u,e),queueMicrotask(()=>{h?.emit("taskFinished",r),this.promiseResponseMap.delete(r),this.checkAndEmitTaskExecutionFinishedEvents(),!0!==this.opts.enableTasksQueue||this.destroying||(!this.isWorkerNodeBusy(u)&&this.tasksQueueSize(u)>0&&this.executeTask(u,this.dequeueTask(u)),this.isWorkerNodeIdle(u)&&h.emit("idle",{workerNodeKey:u})),this.shallCreateDynamicWorker()&&this.createAndSetupDynamicWorkerNode()})}}handleWorkerError=(e,t)=>{const{aborted:r,error:s,message:i,name:o,stack:n}=t;if(r)return this.getAbortError(o,e);if(null!=s)return s;const a=new Error(i);return a.stack=n,a};handleWorkerNodeBackPressureEvent=e=>{if(this.cannotStealTask()||this.backPressure||this.isStealingRatioReached())return;if(this.opts.tasksQueueOptions.size<=1)return;const{workerId:t}=e,r=this.getWorkerNodeKeyByWorkerId(t),s=this.workerNodes[r];if(null==s)return;const i=this.workerNodes.slice().sort((e,t)=>e.usage.tasks.queued-t.usage.tasks.queued);for(const e of i){if(0===s.usage.tasks.queued)break;if(e!==s&&!e.info.backPressureStealing&&e.usage.tasks.queued<this.opts.tasksQueueOptions.size-1){const t=this.workerNodes.indexOf(e);e.info.backPressureStealing=!0,this.stealTask(s,t),e.info.backPressureStealing=!1}}};handleWorkerNodeIdleEvent=(e,t)=>{const{workerNodeKey:r}=e;if(null==r)throw new Error("WorkerNode event detail 'workerNodeKey' property must be defined");const s=this.workerNodes[r];if(null==s)return;if(!s.info.continuousStealing&&(this.cannotStealTask()||this.isStealingRatioReached()))return;const i=s.usage.tasks;if(s.info.continuousStealing&&!this.isWorkerNodeIdle(r))return s.info.continuousStealing=!1,void(i.sequentiallyStolen>0&&this.resetTaskSequentiallyStolenStatisticsWorkerUsage(r,t?.name));s.info.continuousStealing=!0;const o=this.workerNodeStealTask(r);this.updateTaskSequentiallyStolenStatisticsWorkerUsage(r,o?.name,t?.name),(async e=>{await new Promise(t=>{setTimeout(t,e)})})(((e=0,t=100)=>{const r=2**e*t;return r+.2*r*O()})(i.sequentiallyStolen)).then(()=>{this.handleWorkerNodeIdleEvent(e,o)}).catch(e=>{this.emitter?.emit(f.error,e)})};handleWorkerReadyResponse(e){const{ready:t,taskFunctionsProperties:r,workerId:s}=e;if(null==t||!t)throw new Error(`Worker ${s?.toString()} failed to initialize`);const i=this.maximumNumberOfWorkers??this.minimumNumberOfWorkers;for(const e of r??[])L(e.workerNodeKeys,i);const o=this.getWorkerNodeKeyByWorkerId(s),n=this.workerNodes[o];n.info.ready=t,n.info.taskFunctionsProperties=r,this.sendStatisticsMessageToWorker(o),this.setTasksQueuePriority(o),this.checkAndEmitReadyEvent()}initEventEmitter(){this.emitter=new w({name:`poolifier:${this.type}-${this.worker}-pool`})}initWorkerNodeUsage(e){const t=this.workerChoiceStrategiesContext?.getTaskStatisticsRequirements();!0===t?.runTime.aggregate&&(e.usage.runTime.aggregate=C(...this.workerNodes.map(e=>e.usage.runTime.aggregate??Number.POSITIVE_INFINITY))),!0===t?.waitTime.aggregate&&(e.usage.waitTime.aggregate=C(...this.workerNodes.map(e=>e.usage.waitTime.aggregate??Number.POSITIVE_INFINITY))),!0===t?.elu.aggregate&&(e.usage.elu.active.aggregate=C(...this.workerNodes.map(e=>e.usage.elu.active.aggregate??Number.POSITIVE_INFINITY)))}async internalExecute(e,t,r,s){return await new Promise((i,o)=>{const n=y.now(),a=this.chooseWorkerNode(t),u={abortable:null!=r,data:e??{},name:t??T,priority:this.getWorkerNodeTaskFunctionPriority(a,t),strategy:this.getWorkerNodeTaskFunctionWorkerChoiceStrategy(a,t),taskId:d(),timestamp:n,transferList:s};r?.addEventListener("abort",()=>{this.workerNodes[a]?.emit("abortTask",{taskId:u.taskId,workerId:this.getWorkerInfo(a).id})},{once:!0}),this.promiseResponseMap.set(u.taskId,{reject:o,resolve:i,workerNodeKey:a,...null!=this.emitter&&{asyncResource:new m("poolifier:task",{requireManualDestroy:!0,triggerAsyncId:this.emitter.asyncId})},abortSignal:r}),!1===this.opts.enableTasksQueue||!0===this.opts.enableTasksQueue&&this.shallExecuteTask(a)?this.executeTask(a,u):this.enqueueTask(a,u)})}isStealingRatioReached=()=>0===this.opts.tasksQueueOptions?.tasksStealingRatio||this.getStealingWorkerNodes()>Math.ceil(this.workerNodes.length*this.opts.tasksQueueOptions.tasksStealingRatio);isWorkerNodeBackPressured(e){const t=this.workerNodes[e];return null!=t&&(t.info.ready&&t.info.backPressure)}isWorkerNodeBusy(e){const t=this.workerNodes[e];return null!=t&&(!0===this.opts.enableTasksQueue?t.info.ready&&t.usage.tasks.executing>=this.opts.tasksQueueOptions.concurrency:t.info.ready&&t.usage.tasks.executing>0)}isWorkerNodeIdle(e){const t=this.workerNodes[e];return null!=t&&(!0===this.opts.enableTasksQueue?t.info.ready&&0===t.usage.tasks.executing&&0===this.tasksQueueSize(e):t.info.ready&&0===t.usage.tasks.executing)}isWorkerNodeStealing(e){const t=this.workerNodes[e];return null!=t&&(t.info.ready&&(t.info.continuousStealing||t.info.backPressureStealing))}redistributeQueuedTasks(e){if(-1!==e&&!this.cannotStealTask())for(;this.tasksQueueSize(e)>0;){const t=this.workerNodes.reduce((t,r,s,i)=>s!==e&&r.info.ready&&(-1===t||r.usage.tasks.queued<i[t].usage.tasks.queued)?s:t,-1);if(-1===t)break;this.handleTask(t,this.dequeueTask(e))}}removeWorkerNode(e){const t=this.workerNodes.indexOf(e);-1!==t&&(this.workerNodes.splice(t,1),this.workerChoiceStrategiesContext?.remove(t),e.info.dynamic&&this.checkAndEmitDynamicWorkerDestructionEvents())}resetTaskSequentiallyStolenStatisticsWorkerUsage(e,t){const r=this.workerNodes[e];null!=r?.usage&&(r.usage.tasks.sequentiallyStolen=0),null!=t&&this.shallUpdateTaskFunctionWorkerUsage(e)&&null!=r.getTaskFunctionWorkerUsage(t)&&(r.getTaskFunctionWorkerUsage(t).tasks.sequentiallyStolen=0)}async sendKillMessageToWorker(e,t=1e3){let r,s;try{await new Promise((i,o)=>{r=t>=0?setTimeout(()=>{i()},t):void 0,s=t=>{0!==this.workerNodes.length&&null!=this.workerNodes[e]?"success"===t.kill?i():"failure"===t.kill&&o(new Error(`Kill message handling failed on worker ${t.workerId?.toString()}`)):i()},this.registerWorkerMessageListener(e,s),this.sendToWorker(e,{kill:!0})})}finally{null!=r&&clearTimeout(r),null!=s&&this.deregisterWorkerMessageListener(e,s)}}sendStatisticsMessageToWorker(e){const t=this.workerChoiceStrategiesContext?.getTaskStatisticsRequirements();this.sendToWorker(e,{statistics:{elu:t?.elu.aggregate??!1,runTime:t?.runTime.aggregate??!1}})}async sendTaskFunctionOperationToWorker(e,t){let r;try{return await new Promise((s,i)=>{r=t=>{this.checkMessageWorkerId(t);const r=this.getWorkerInfo(e)?.id;if(null!=t.taskFunctionOperationStatus&&t.workerId===r){if(t.taskFunctionOperationStatus)return void s(!0);i(new Error(`Task function operation '${t.taskFunctionOperation?.toString()}' failed on worker ${t.workerId?.toString()} with error: '${t.workerError?.message}'`))}},this.registerWorkerMessageListener(e,r),this.sendToWorker(e,t)})}finally{null!=r&&this.deregisterWorkerMessageListener(e,r)}}async sendTaskFunctionOperationToWorkers(e){const t=this.workerNodes.length;if(0===t)return!0;const r=[],s=(e,s,i)=>{this.checkMessageWorkerId(e);const o=this.getWorkerNodeKeyByWorkerId(e.workerId);if(null!=e.taskFunctionOperationStatus&&o>=0&&o<t&&(r.push(e),r.length>=t))if(r.every(e=>!0===e.taskFunctionOperationStatus))s(!0);else{const t=r.find(e=>!1===e.taskFunctionOperationStatus);i(new Error(`Task function operation '${e.taskFunctionOperation}' failed on worker ${t?.workerId?.toString()} with error: '${t?.workerError?.error?.message??"Unknown error"}'`))}};let i;const o=[...this.workerNodes.keys()];try{return await new Promise((t,r)=>{i=e=>{s(e,t,r)};for(const t of o)this.registerWorkerMessageListener(t,i),this.sendToWorker(t,e)})}finally{if(null!=i)for(const e of o)this.deregisterWorkerMessageListener(e,i)}}setTasksQueuePriority(e){this.workerNodes[e].setTasksQueuePriority(this.getTasksQueuePriority())}setTasksQueueSize(e){for(const t of this.workerNodes)t.tasksQueueBackPressureSize=e}setTasksStealingOnBackPressure(){for(const e of this.workerNodes.keys())this.workerNodes[e].on("backPressure",this.handleWorkerNodeBackPressureEvent)}setTaskStealing(){for(const e of this.workerNodes.keys())this.workerNodes[e].on("idle",this.handleWorkerNodeIdleEvent)}shallExecuteTask(e){return 0===this.tasksQueueSize(e)&&this.workerNodes[e].usage.tasks.executing<this.opts.tasksQueueOptions.concurrency}shallUpdateTaskFunctionWorkerUsage(e){const t=this.getWorkerInfo(e);return null!=t&&Array.isArray(t.taskFunctionsProperties)&&t.taskFunctionsProperties.length>2}startMinimumNumberOfWorkers(e=!1){if(0!==this.minimumNumberOfWorkers){for(this.startingMinimumNumberOfWorkers=!0;this.workerNodes.reduce((e,t)=>t.info.dynamic?e:e+1,0)<this.minimumNumberOfWorkers;){const t=this.createAndSetupWorkerNode();e&&this.initWorkerNodeUsage(this.workerNodes[t])}this.startingMinimumNumberOfWorkers=!1}}stealTask=(e,t)=>{const r=this.workerNodes[t];if(null==r)return;if(!e.info.ready||e.info.stolen||e.info.stealing||e.info.queuedTaskAbortion||!r.info.ready||r.info.stolen||r.info.stealing||r.info.queuedTaskAbortion)return;r.info.stealing=!0,e.info.stolen=!0;const s=e.dequeueLastPrioritizedTask();return null==s?(e.info.stolen=!1,void(r.info.stealing=!1)):(e.info.stolen=!1,r.info.stealing=!1,this.handleTask(t,s),this.updateTaskStolenStatisticsWorkerUsage(t,s.name),s)};tasksQueueSize(e){const t=this.workerNodes[e];return null==t?0:t.tasksQueueSize()}unsetTasksStealingOnBackPressure(){for(const e of this.workerNodes.keys())this.workerNodes[e].off("backPressure",this.handleWorkerNodeBackPressureEvent)}unsetTaskStealing(){for(const e of this.workerNodes.keys())this.workerNodes[e].off("idle",this.handleWorkerNodeIdleEvent)}updateTaskSequentiallyStolenStatisticsWorkerUsage(e,t,r){const s=this.workerNodes[e];if(null!=s?.usage&&null!=t&&++s.usage.tasks.sequentiallyStolen,null!=t&&this.shallUpdateTaskFunctionWorkerUsage(e)&&null!=s.getTaskFunctionWorkerUsage(t)){const e=s.getTaskFunctionWorkerUsage(t);0===e.tasks.sequentiallyStolen||null!=r&&r===t&&e.tasks.sequentiallyStolen>0?++e.tasks.sequentiallyStolen:e.tasks.sequentiallyStolen>0&&(e.tasks.sequentiallyStolen=0)}}updateTaskStolenStatisticsWorkerUsage(e,t){const r=this.workerNodes[e];null!=r?.usage&&++r.usage.tasks.stolen,this.shallUpdateTaskFunctionWorkerUsage(e)&&null!=r.getTaskFunctionWorkerUsage(t)&&++r.getTaskFunctionWorkerUsage(t).tasks.stolen}workerNodeStealTask=e=>{const t=this.workerNodes[e];if(null==t)return;const r=this.workerNodes.slice().sort((e,t)=>t.usage.tasks.queued-e.usage.tasks.queued).find(e=>e!==t&&e.usage.tasks.queued>0);return null!=r?this.stealTask(r,e):void 0}}class We extends Te{get backPressure(){return this.internalBackPressure()}get busy(){return this.internalBusy()}get type(){return p.fixed}get worker(){return q.cluster}constructor(e,t,r={},s){super(e,t,r,s)}checkAndEmitDynamicWorkerCreationEvents(){}checkAndEmitDynamicWorkerDestructionEvents(){}deregisterWorkerMessageListener(e,t){this.workerNodes[e]?.worker.off("message",t)}isMain(){return e.isPrimary}registerOnceWorkerMessageListener(e,t){this.workerNodes[e]?.worker.once("message",t)}registerWorkerMessageListener(e,t){this.workerNodes[e]?.worker.on("message",t)}sendStartupMessageToWorker(e){this.sendToWorker(e,{ready:!1})}sendToWorker(e,t){this.workerNodes[e]?.worker.send({...t,workerId:this.getWorkerInfo(e)?.id})}setupHook(){e.setupPrimary({...this.opts.settings,exec:this.filePath})}shallCreateDynamicWorker(){return!1}}class Ee extends We{get backPressure(){return this.full&&this.internalBackPressure()}get busy(){return this.full&&this.internalBusy()}get type(){return p.dynamic}emptyEventEmitted;fullEventEmitted;get empty(){return 0===this.minimumNumberOfWorkers&&this.workerNodes.length===this.minimumNumberOfWorkers}get full(){return this.workerNodes.length>=(this.maximumNumberOfWorkers??this.minimumNumberOfWorkers)}constructor(e,t,r,s={}){super(e,r,s,t),U(this.minimumNumberOfWorkers,this.maximumNumberOfWorkers),this.emptyEventEmitted=!1,this.fullEventEmitted=!1}checkAndEmitDynamicWorkerCreationEvents(){null!=this.emitter&&(!this.fullEventEmitted&&this.full&&(this.emitter.listenerCount(f.full)>0&&this.emitter.emit(f.full,this.info),this.fullEventEmitted=!0),this.emptyEventEmitted&&!this.empty&&(this.emptyEventEmitted=!1))}checkAndEmitDynamicWorkerDestructionEvents(){null!=this.emitter&&(this.fullEventEmitted&&!this.full&&(this.emitter.listenerCount(f.fullEnd)>0&&this.emitter.emit(f.fullEnd,this.info),this.fullEventEmitted=!1),!this.emptyEventEmitted&&this.empty&&(this.emitter.listenerCount(f.empty)>0&&this.emitter.emit(f.empty,this.info),this.emptyEventEmitted=!0))}shallCreateDynamicWorker(){return this.started&&!this.destroying&&(!this.full&&this.internalBusy()||this.empty)}}class Se extends Te{get backPressure(){return this.internalBackPressure()}get busy(){return this.internalBusy()}get type(){return p.fixed}get worker(){return q.thread}constructor(e,t,r={},s){super(e,t,r,s)}checkAndEmitDynamicWorkerCreationEvents(){}checkAndEmitDynamicWorkerDestructionEvents(){}deregisterWorkerMessageListener(e,t){this.workerNodes[e]?.messageChannel?.port1.off("message",t)}isMain(){return a}registerOnceWorkerMessageListener(e,t){this.workerNodes[e]?.messageChannel?.port1.once("message",t)}registerWorkerMessageListener(e,t){this.workerNodes[e]?.messageChannel?.port1.on("message",t)}sendStartupMessageToWorker(e){const t=this.workerNodes[e],r=t.messageChannel.port2;t.worker.postMessage({port:r,ready:!1,workerId:this.getWorkerInfo(e)?.id},[r])}sendToWorker(e,t,r){this.workerNodes[e]?.messageChannel?.port1.postMessage({...t,workerId:this.getWorkerInfo(e)?.id},r)}shallCreateDynamicWorker(){return!1}}class be extends Se{get backPressure(){return this.full&&this.internalBackPressure()}get busy(){return this.full&&this.internalBusy()}get type(){return p.dynamic}emptyEventEmitted;fullEventEmitted;get empty(){return 0===this.minimumNumberOfWorkers&&this.workerNodes.length===this.minimumNumberOfWorkers}get full(){return this.workerNodes.length>=(this.maximumNumberOfWorkers??this.minimumNumberOfWorkers)}constructor(e,t,r,s={}){super(e,r,s,t),U(this.minimumNumberOfWorkers,this.maximumNumberOfWorkers),this.emptyEventEmitted=!1,this.fullEventEmitted=!1}checkAndEmitDynamicWorkerCreationEvents(){null!=this.emitter&&(!this.fullEventEmitted&&this.full&&(this.emitter.listenerCount(f.full)>0&&this.emitter.emit(f.full,this.info),this.fullEventEmitted=!0),this.emptyEventEmitted&&!this.empty&&(this.emptyEventEmitted=!1))}checkAndEmitDynamicWorkerDestructionEvents(){null!=this.emitter&&(this.fullEventEmitted&&!this.full&&(this.emitter.listenerCount(f.fullEnd)>0&&this.emitter.emit(f.fullEnd,this.info),this.fullEventEmitted=!1),!this.emptyEventEmitted&&this.empty&&(this.emitter.listenerCount(f.empty)>0&&this.emitter.emit(f.empty,this.info),this.emptyEventEmitted=!0))}shallCreateDynamicWorker(){return this.started&&!this.destroying&&(!this.full&&this.internalBusy()||this.empty)}}class ve extends Error{constructor(e){super(e),this.name="AbortError"}}const xe=(e,t)=>{if(Ie(e),"function"!=typeof t.taskFunction)throw new TypeError(`taskFunction object 'taskFunction' property '${t.taskFunction}' is not a function`);B(t.priority),_(t.strategy),L(t.workerNodeKeys)},Ie=e=>{if("string"!=typeof e)throw new TypeError("name parameter is not a string");if(0===e.trim().length)throw new TypeError("name parameter is an empty string")},Fe=6e4,Oe=Object.freeze({killBehavior:Z.SOFT,killHandler:W,maxInactiveTime:Fe});class Ce{isMain;mainWorker;opts;activeInterval;lastTaskTimestamp;statistics;taskAbortFunctions;taskFunctions;constructor(e,t,r,s=Oe){if(this.isMain=e,this.mainWorker=t,this.opts=s,null==this.isMain)throw new Error("isMain parameter is mandatory");this.checkTaskFunctions(r),this.taskAbortFunctions=new Map,this.checkWorkerOptions(this.opts),this.isMain||this.getMainWorker().once("message",this.handleReadyMessage.bind(this))}addTaskFunction(e,t){try{if(Ie(e),e===T)throw new Error("Cannot add a task function with the default reserved name");return"function"==typeof t&&(t={taskFunction:t}),xe(e,t),t.taskFunction=t.taskFunction.bind(this),this.taskFunctions.get(e)===this.taskFunctions.get(T)&&this.taskFunctions.set(T,t),this.taskFunctions.set(e,t),this.sendTaskFunctionsPropertiesToMainWorker(),{status:!0}}catch(e){return{error:e,status:!1}}}hasTaskFunction(e){try{Ie(e)}catch(e){return{error:e,status:!1}}return{status:this.taskFunctions.has(e)}}listTaskFunctionsProperties(){let e=T;for(const[t,r]of this.taskFunctions)if(t!==T&&r===this.taskFunctions.get(T)){e=t;break}const t=[];for(const[r,s]of this.taskFunctions)r!==T&&r!==e&&t.push(A(r,s));return[A(T,this.taskFunctions.get(T)),A(e,this.taskFunctions.get(e)),...t]}removeTaskFunction(e){try{if(Ie(e),e===T)throw new Error("Cannot remove the task function with the default reserved name");if(this.taskFunctions.get(e)===this.taskFunctions.get(T))throw new Error("Cannot remove the task function used as the default task function");const t=this.taskFunctions.delete(e);return this.sendTaskFunctionsPropertiesToMainWorker(),{status:t}}catch(e){return{error:e,status:!1}}}setDefaultTaskFunction(e){try{if(Ie(e),e===T)throw new Error("Cannot set the default task function reserved name as the default task function");if(!this.taskFunctions.has(e))throw new Error("Cannot set the default task function to a non-existing task function");return this.taskFunctions.set(T,this.taskFunctions.get(e)),this.sendTaskFunctionsPropertiesToMainWorker(),{status:!0}}catch(e){return{error:e,status:!1}}}getMainWorker(){if(null==this.mainWorker)throw new Error("Main worker not set");return this.mainWorker}handleKillMessage(e){if(this.stopCheckActive(),F(this.opts.killHandler))this.opts.killHandler().then(()=>{this.sendToMainWorker({kill:"success"})}).catch(()=>{this.sendToMainWorker({kill:"failure"})});else try{this.opts.killHandler?.(),this.sendToMainWorker({kill:"success"})}catch{this.sendToMainWorker({kill:"failure"})}}handleTaskFunctionOperationMessage(e){const{taskFunction:t,taskFunctionOperation:r,taskFunctionProperties:s}=e;if(null==s)throw new Error("Cannot handle task function operation message without task function properties");let i;switch(r){case"add":if("string"!=typeof t)throw new Error(`Cannot handle task function operation ${r} message without task function`);i=this.addTaskFunction(s.name,{taskFunction:new Function(`return (${t})`)(),...null!=s.priority&&{priority:s.priority},...null!=s.strategy&&{strategy:s.strategy},...null!=s.workerNodeKeys&&{workerNodeKeys:s.workerNodeKeys}});break;case"default":i=this.setDefaultTaskFunction(s.name);break;case"remove":i=this.removeTaskFunction(s.name);break;default:i={error:new Error(`Unknown task function operation: ${r}`),status:!1}}const{error:o,status:n}=i;this.sendToMainWorker({taskFunctionOperation:r,taskFunctionOperationStatus:n,taskFunctionProperties:s,...!n&&null!=o&&{workerError:{name:s.name,...this.handleError(o)}}})}messageListener(e){this.checkMessageWorkerId(e);const{checkActive:t,data:r,kill:s,statistics:i,taskFunctionOperation:o,taskId:n,taskOperation:a}=e;null!=i?this.statistics=i:null!=t?t?this.startCheckActive():this.stopCheckActive():null!=o?this.handleTaskFunctionOperationMessage(e):null!=n&&null!=r?this.run(e):"abort"===a&&null!=n?this.taskAbortFunctions.has(n)&&this.taskAbortFunctions.get(n)?.():!0===s&&this.handleKillMessage(e)}run=e=>{const{abortable:t,data:r,name:s,taskId:i}=e,o=s??T;if(!this.taskFunctions.has(o))return void this.sendToMainWorker({taskId:i,workerError:{data:r,name:s,...this.handleError(new Error(`Task function '${o}' not found`))}});let n;n=!0===t?this.getAbortableTaskFunction(o,i):this.taskFunctions.get(o).taskFunction,F(n)?this.runAsync(n,e):this.runSync(n,e)};runAsync=(e,t)=>{const{abortable:r,data:s,name:i,taskId:o}=t;let n=this.beginTaskPerformance(i);e(s).then(e=>{n=this.endTaskPerformance(n),this.sendToMainWorker({data:e,taskId:o,taskPerformance:n})}).catch(e=>{this.sendToMainWorker({taskId:o,workerError:{data:s,name:i,...this.handleError(e)}})}).finally(()=>{this.updateLastTaskTimestamp(),!0===r&&this.taskAbortFunctions.delete(o)}).catch(W)};runSync=(e,t)=>{const{abortable:r,data:s,name:i,taskId:o}=t;try{let t=this.beginTaskPerformance(i);const r=e(s);t=this.endTaskPerformance(t),this.sendToMainWorker({data:r,taskId:o,taskPerformance:t})}catch(e){this.sendToMainWorker({taskId:o,workerError:{data:s,name:i,...this.handleError(e)}})}finally{this.updateLastTaskTimestamp(),!0===r&&this.taskAbortFunctions.delete(o)}};sendTaskFunctionsPropertiesToMainWorker(){this.sendToMainWorker({taskFunctionsProperties:this.listTaskFunctionsProperties()})}beginTaskPerformance(e){if(null==this.statistics)throw new Error("Performance statistics computation requirements not set");return{name:e??T,timestamp:y.now(),...this.statistics.elu&&{elu:y.eventLoopUtilization()}}}checkActive(){y.now()-this.lastTaskTimestamp>(this.opts.maxInactiveTime??Fe)&&this.sendToMainWorker({kill:this.opts.killBehavior})}checkMessageWorkerId(e){if(null==e.workerId)throw new Error(`Message worker id is not set: ${JSON.stringify(e)}`);if(e.workerId!==this.id)throw new Error(`Message worker id ${e.workerId.toString()} does not match the worker id ${this.id.toString()}: ${JSON.stringify(e)}`)}checkTaskFunctions(e){if(null==e)throw new Error("taskFunctions parameter is mandatory");if(this.taskFunctions=new Map,"function"==typeof e){const t={taskFunction:e.bind(this)};this.taskFunctions.set(T,t),this.taskFunctions.set("string"==typeof e.name&&e.name.trim().length>0?e.name:"fn1",t)}else{if(!x(e))throw new TypeError("taskFunctions parameter is not a function or a plain object");{let t=!0;for(let[r,s]of Object.entries(e))"function"==typeof s&&(s={taskFunction:s}),xe(r,s),s.taskFunction=s.taskFunction.bind(this),t&&(this.taskFunctions.set(T,s),t=!1),this.taskFunctions.set(r,s);if(t)throw new Error("taskFunctions parameter object is empty")}}}checkWorkerOptions(e){(e=>{if(null!=e&&!x(e))throw new TypeError("opts worker options parameter is not a plain object");if(null!=e?.killBehavior&&!Object.values(Z).includes(e.killBehavior))throw new TypeError(`killBehavior option '${e.killBehavior}' is not valid`);if(null!=e?.maxInactiveTime&&(!Number.isSafeInteger(e.maxInactiveTime)||e.maxInactiveTime<5))throw new TypeError("maxInactiveTime option is not a positive integer greater or equal than 5");if(null!=e?.killHandler&&"function"!=typeof e.killHandler)throw new TypeError("killHandler option is not a function")})(e),this.opts={...Oe,...e}}endTaskPerformance(e){if(null==this.statistics)throw new Error("Performance statistics computation requirements not set");return{...e,...this.statistics.runTime&&{runTime:y.now()-e.timestamp},...this.statistics.elu&&{elu:y.eventLoopUtilization(e.elu)}}}getAbortableTaskFunction(e,t){return async r=>await new Promise((s,i)=>{this.taskAbortFunctions.set(t,()=>{i(new ve(`Task '${e}' id '${t}' aborted`))});const o=this.taskFunctions.get(e).taskFunction;F(o)?o(r).then(s).catch(i):s(o(r))})}startCheckActive(){this.lastTaskTimestamp=y.now(),this.activeInterval=setInterval(this.checkActive.bind(this),(this.opts.maxInactiveTime??Fe)/2),this.activeInterval.unref()}stopCheckActive(){null!=this.activeInterval&&(clearInterval(this.activeInterval),this.activeInterval=void 0)}updateLastTaskTimestamp(){null!=this.activeInterval&&(this.lastTaskTimestamp=y.now())}}class Pe extends Ce{get id(){return this.getMainWorker().id}constructor(t,r={}){super(e.isPrimary,e.worker,t,r)}handleError(e){return{aborted:e instanceof ve,message:e.message,stack:e.stack}}handleReadyMessage(e){if(e.workerId===this.id&&!1===e.ready)try{this.getMainWorker().on("message",this.messageListener.bind(this)),this.sendToMainWorker({ready:!0,taskFunctionsProperties:this.listTaskFunctionsProperties()})}catch{this.sendToMainWorker({ready:!1,taskFunctionsProperties:this.listTaskFunctionsProperties()})}}sendToMainWorker=e=>{this.getMainWorker().send({...e,workerId:this.id})}}class Ae extends Ce{get id(){return u}port;constructor(e,t={}){super(a,h,e,t)}handleError(e){return{aborted:e instanceof ve,error:e,message:e.message,stack:e.stack}}handleKillMessage(e){super.handleKillMessage(e),this.port?.unref(),this.port?.close()}handleReadyMessage(e){if(e.workerId===this.id&&!1===e.ready&&null!=e.port)try{this.port=e.port,this.port.on("message",this.messageListener.bind(this)),this.sendToMainWorker({ready:!0,taskFunctionsProperties:this.listTaskFunctionsProperties()})}catch{this.sendToMainWorker({ready:!1,taskFunctionsProperties:this.listTaskFunctionsProperties()})}}sendToMainWorker=e=>{this.port?.postMessage({...e,workerId:this.id})}}export{Pe as ClusterWorker,Ee as DynamicClusterPool,be as DynamicThreadPool,We as FixedClusterPool,Se as FixedThreadPool,Z as KillBehaviors,R as Measurements,f as PoolEvents,p as PoolTypes,Ae as ThreadWorker,z as WorkerChoiceStrategies,q as WorkerTypes,E as availableParallelism};
1
+ import e,{Worker as t}from"node:cluster";import{existsSync as r}from"node:fs";import{Worker as s,SHARE_ENV as i,MessageChannel as o,isMainThread as n,threadId as a,parentPort as u}from"node:worker_threads";import{getRandomValues as h,randomUUID as k}from"node:crypto";import*as d from"node:os";import{cpus as l}from"node:os";import{AsyncResource as c}from"node:async_hooks";import{EventEmitter as m,EventEmitterAsyncResource as g}from"node:events";import{performance as y}from"node:perf_hooks";const w=Object.freeze({dynamic:"dynamic",fixed:"fixed"}),f=Object.freeze({backPressure:"backPressure",backPressureEnd:"backPressureEnd",busy:"busy",busyEnd:"busyEnd",destroy:"destroy",empty:"empty",error:"error",full:"full",fullEnd:"fullEnd",ready:"ready",taskError:"taskError"}),p=1/1.5,N="default",T=Object.freeze(()=>{}),W=()=>{let e=1;try{e=d.availableParallelism()}catch{const t=d.cpus();Array.isArray(t)&&t.length>0&&(e=t.length)}return e},E=e=>Array.isArray(e)&&0!==e.length?1===e.length?e[0]:e.reduce((e,t)=>e+t,0)/e.length:0,S=e=>{if(!Array.isArray(e)||0===e.length)return 0;if(1===e.length)return e[0];const t=e.slice().sort((e,t)=>e-t);return(t[t.length-1>>1]+t[t.length>>1])/2},b=(e,t=2)=>{const r=10**t;return Math.round((e+Math.sign(e)*Number.EPSILON)*r)/r},v=e=>"object"==typeof e&&null!==e&&e.constructor===Object&&"[object Object]"===Object.prototype.toString.call(e),x=(e,t)=>t===e,I=e=>e?.constructor===(async()=>{}).constructor,F=()=>h(new Uint32Array(1))[0]/4294967296,O=(...e)=>e.reduce((e,t)=>e<t?e:t,Number.POSITIVE_INFINITY),C=(...e)=>e.reduce((e,t)=>e>t?e:t,Number.NEGATIVE_INFINITY),P=(e,t)=>({name:e,...null!=t?.priority&&{priority:t.priority},...null!=t?.strategy&&{strategy:t.strategy},...null!=t?.workerNodeKeys&&{workerNodeKeys:t.workerNodeKeys}}),A=Object.freeze({FAIR_SHARE:"FAIR_SHARE",INTERLEAVED_WEIGHTED_ROUND_ROBIN:"INTERLEAVED_WEIGHTED_ROUND_ROBIN",LEAST_BUSY:"LEAST_BUSY",LEAST_ELU:"LEAST_ELU",LEAST_USED:"LEAST_USED",ROUND_ROBIN:"ROUND_ROBIN",WEIGHTED_ROUND_ROBIN:"WEIGHTED_ROUND_ROBIN"}),z=Object.freeze({elu:"elu",runTime:"runTime",waitTime:"waitTime"}),R=386,K=Object.freeze({cluster:"cluster",thread:"thread"}),q=Object.freeze({aggregate:!1,average:!1,median:!1}),M=e=>Object.freeze({agingFactor:.001,concurrency:1,loadExponent:p,size:e**2,tasksFinishedTimeout:2e3,tasksStealingOnBackPressure:!0,tasksStealingRatio:.6,taskStealing:!0}),Q=e=>{if(null==e)throw new TypeError("The worker file path must be defined");if("string"!=typeof e)throw new TypeError("The worker file path must be a string");if(!r(e))throw new Error(`Cannot find the worker file '${e}'`)},U=(e,t)=>{if(null==t)throw new TypeError("Cannot instantiate a dynamic pool without specifying the maximum pool size");if(!Number.isSafeInteger(t))throw new TypeError("Cannot instantiate a dynamic pool with a non safe integer maximum pool size");if(e>t)throw new RangeError("Cannot instantiate a dynamic pool with a maximum pool size inferior to the minimum pool size");if(0===t)throw new RangeError("Cannot instantiate a dynamic pool with a maximum pool size equal to zero");if(e===t)throw new RangeError("Cannot instantiate a dynamic pool with a minimum pool size equal to the maximum pool size. Use a fixed pool instead")},D=e=>{if(null!=e&&!Number.isSafeInteger(e))throw new TypeError(`Invalid property 'priority': '${e.toString()}'`);if(null!=e&&Number.isSafeInteger(e)&&(e<-20||e>19))throw new RangeError("Property 'priority' must be between -20 and 19")},B=e=>{if(null!=e&&!Object.values(A).includes(e))throw new Error(`Invalid worker choice strategy '${e}'`)},_=(e,t)=>{if(null!=e&&!Array.isArray(e))throw new TypeError("Invalid worker node keys: must be an array");if(0===e?.length)throw new RangeError("Invalid worker node keys: must not be an empty array");if(null!=e)for(const t of e)if(!Number.isSafeInteger(t)||t<0)throw new TypeError(`Invalid worker node key '${t.toString()}': must be a non-negative safe integer`);if(null!=e&&new Set(e).size!==e.length)throw new TypeError("Invalid worker node keys: must not contain duplicates");if(null!=t&&null!=e){if(e.length>t)throw new RangeError("Cannot add a task function with more worker node keys than the maximum number of workers in the pool");const r=e.filter(e=>e>=t);if(r.length>0)throw new RangeError(`Cannot add a task function with invalid worker node keys: ${r.toString()}. Valid keys are: 0..${(t-1).toString()}`)}},L=e=>{if(null!=e&&!v(e))throw new TypeError("Invalid tasks queue options: must be a plain object");if(null!=e?.concurrency&&!Number.isSafeInteger(e.concurrency))throw new TypeError("Invalid worker node tasks concurrency: must be an integer");if(null!=e?.concurrency&&e.concurrency<=0)throw new RangeError(`Invalid worker node tasks concurrency: ${e.concurrency.toString()} is a negative integer or zero`);if(null!=e?.size&&!Number.isSafeInteger(e.size))throw new TypeError("Invalid worker node tasks queue size: must be an integer");if(null!=e?.size&&e.size<=0)throw new RangeError(`Invalid worker node tasks queue size: ${e.size.toString()} is a negative integer or zero`);if(null!=e?.agingFactor&&"number"!=typeof e.agingFactor)throw new TypeError("Invalid worker node tasks queue aging factor: must be a number");if(null!=e?.agingFactor&&e.agingFactor<0)throw new RangeError("Invalid worker node tasks queue aging factor: must be greater than or equal to 0");if(null!=e?.loadExponent&&"number"!=typeof e.loadExponent)throw new TypeError("Invalid worker node tasks queue load exponent: must be a number");if(null!=e?.loadExponent&&e.loadExponent<=0)throw new RangeError("Invalid worker node tasks queue load exponent: must be greater than 0");if(null!=e?.tasksStealingRatio&&"number"!=typeof e.tasksStealingRatio)throw new TypeError("Invalid worker node tasks stealing ratio: must be a number");if(null!=e?.tasksStealingRatio&&(e.tasksStealingRatio<0||e.tasksStealingRatio>1))throw new RangeError("Invalid worker node tasks stealing ratio: must be between 0 and 1")},$=(e,t,r)=>{null!=t&&null!=r&&t.aggregate&&(e.aggregate=(e.aggregate??0)+r,e.minimum=O(r,e.minimum??Number.POSITIVE_INFINITY),e.maximum=C(r,e.maximum??Number.NEGATIVE_INFINITY),(t.average||t.median)&&(e.history.put(r),t.average?e.average=E(e.history.toArray()):null!=e.average&&(e.average=void 0),t.median?e.median=S(e.history.toArray()):null!=e.median&&(e.median=void 0)))},V=(e,t,r)=>{const s=performance.now(),i=s-(r.timestamp??s);$(t.waitTime,e?.getTaskStatisticsRequirements().waitTime,i)},H=(e,t)=>{const r=e.tasks;null!=r.executing&&r.executing>0&&--r.executing,null==t.workerError?++r.executed:++r.failed},j=(e,t,r)=>{null==r.workerError&&$(t.runTime,e?.getTaskStatisticsRequirements().runTime,r.taskPerformance?.runTime??0)},Y=(e,t,r)=>{if(null!=r.workerError)return;const s=e?.getTaskStatisticsRequirements().elu;$(t.elu.active,s,r.taskPerformance?.elu?.active??0),$(t.elu.idle,s,r.taskPerformance?.elu?.idle??0),!0===s?.aggregate&&null!=r.taskPerformance?.elu&&(t.elu.count=(t.elu.count??0)+1,t.elu.utilization=((t.elu.utilization??0)*(t.elu.count-1)+r.taskPerformance.elu.utilization)/t.elu.count)},G=e=>e instanceof s?K.thread:e instanceof t?K.cluster:void 0,J=e=>e instanceof s?e.threadId:e instanceof t?e.id:void 0,X=Object.freeze({HARD:"HARD",SOFT:"SOFT"});class Z{pool;opts;retriesCount;strategyPolicy=Object.freeze({dynamicWorkerReady:!0,dynamicWorkerUsage:!1});taskStatisticsRequirements=Object.freeze({elu:{...q},runTime:{...q},waitTime:{...q}});nextWorkerNodeKey;previousWorkerNodeKey;constructor(e,t){this.pool=e,this.opts=t,this.retriesCount=0,this.nextWorkerNodeKey=0,this.previousWorkerNodeKey=0,this.choose=this.choose.bind(this),this.setOptions(this.opts)}setOptions(e){this.opts=he(this.pool,e),this.setTaskStatisticsRequirements(this.opts)}checkWorkerNodeKey(e){if(!(null==e||e<0||e>=this.pool.workerNodes.length))return e}getRoundRobinNextWorkerNodeKey(){return this.nextWorkerNodeKey===this.pool.workerNodes.length-1?0:(this.nextWorkerNodeKey??this.previousWorkerNodeKey)+1}getSingleWorkerNodeKey(e){const[t]=e;return this.isWorkerNodeReady(t)?t:void 0}getWorkerNodeTaskElu(e){return this.taskStatisticsRequirements.elu.median?this.pool.workerNodes[e]?.usage.elu.active.median??0:this.pool.workerNodes[e]?.usage.elu.active.average??0}getWorkerNodeTaskRunTime(e){return this.taskStatisticsRequirements.runTime.median?this.pool.workerNodes[e]?.usage.runTime.median??0:this.pool.workerNodes[e]?.usage.runTime.average??0}getWorkerNodeTaskWaitTime(e){return this.taskStatisticsRequirements.waitTime.median?this.pool.workerNodes[e]?.usage.waitTime.median??0:this.pool.workerNodes[e]?.usage.waitTime.average??0}isWorkerNodeEligible(e,t){return this.isWorkerNodeReady(e)&&(null==t||t.has(e))}isWorkerNodeReady(e){return this.pool.workerNodes[e]?.info.ready??!1}resetWorkerNodeKeyProperties(){this.nextWorkerNodeKey=0,this.previousWorkerNodeKey=0}setPreviousWorkerNodeKey(e){this.previousWorkerNodeKey=null!=e&&e>=0&&e<this.pool.workerNodes.length?e:this.previousWorkerNodeKey}setTaskStatisticsRequirements(e){ke(this.taskStatisticsRequirements.runTime,e.runTime.median),ke(this.taskStatisticsRequirements.waitTime,e.waitTime.median),ke(this.taskStatisticsRequirements.elu,e.elu.median)}}class ee extends Z{name=A.FAIR_SHARE;taskStatisticsRequirements=Object.freeze({elu:{aggregate:!0,average:!0,median:!1},runTime:{aggregate:!0,average:!0,median:!1},waitTime:{aggregate:!0,average:!0,median:!1}});constructor(e,t){super(e,t),this.setTaskStatisticsRequirements(this.opts)}choose(e){return this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey),this.nextWorkerNodeKey=this.fairShareNextWorkerNodeKey(e),this.nextWorkerNodeKey}remove(e){return null!=this.pool.workerNodes[e]?.strategyData?.virtualTaskEndTimestamp&&(this.pool.workerNodes[e].strategyData.virtualTaskEndTimestamp=void 0),!0}reset(){for(const e of this.pool.workerNodes)null!=e.strategyData?.virtualTaskEndTimestamp&&(e.strategyData.virtualTaskEndTimestamp=void 0);return!0}update(e){return this.pool.workerNodes[e].strategyData={...this.pool.workerNodes[e].strategyData,virtualTaskEndTimestamp:this.computeWorkerNodeVirtualTaskEndTimestamp(e)},!0}computeWorkerNodeVirtualTaskEndTimestamp(e){return this.getWorkerNodeVirtualTaskEndTimestamp(e,this.getWorkerNodeVirtualTaskStartTimestamp(e))}fairShareNextWorkerNodeKey(e){if(0===e?.size)return;if(1===e?.size)return this.getSingleWorkerNodeKey(e);const t=this.pool.workerNodes.reduce((t,r,s,i)=>this.isWorkerNodeEligible(s,e)?(null==r.strategyData?.virtualTaskEndTimestamp&&(r.strategyData={...r.strategyData,virtualTaskEndTimestamp:this.computeWorkerNodeVirtualTaskEndTimestamp(s)}),-1===t||r.strategyData.virtualTaskEndTimestamp<i[t].strategyData.virtualTaskEndTimestamp?s:t):t,-1);return-1===t?void 0:t}getWorkerNodeVirtualTaskEndTimestamp(e,t){return t+(this.getWorkerNodeTaskWaitTime(e)+(this.opts?.measurement===z.elu?this.getWorkerNodeTaskElu(e):this.getWorkerNodeTaskRunTime(e)))}getWorkerNodeVirtualTaskStartTimestamp(e){const t=this.pool.workerNodes[e]?.strategyData?.virtualTaskEndTimestamp,r=performance.now();return r<(t??Number.NEGATIVE_INFINITY)?t:r}}class te extends Z{name=A.INTERLEAVED_WEIGHTED_ROUND_ROBIN;taskStatisticsRequirements=Object.freeze({elu:{...q},runTime:{aggregate:!0,average:!0,median:!1},waitTime:{aggregate:!0,average:!0,median:!1}});roundId=0;roundWeights;workerNodeId=0;workerNodeVirtualTaskExecutionTime=0;constructor(e,t){super(e,t),this.setTaskStatisticsRequirements(this.opts),this.roundWeights=this.getRoundWeights()}choose(e){if(0!==e?.size){if(1===e?.size)return this.getSingleWorkerNodeKey(e);for(let t=this.roundId;t<this.roundWeights.length;t++){this.roundId=t;for(let r=this.workerNodeId;r<this.pool.workerNodes.length;r++){this.workerNodeId=r,this.workerNodeId!==this.nextWorkerNodeKey&&0!==this.workerNodeVirtualTaskExecutionTime&&(this.workerNodeVirtualTaskExecutionTime=0);const s=this.opts.weights[r];if(this.isWorkerNodeEligible(r,e)&&s>=this.roundWeights[t]&&this.workerNodeVirtualTaskExecutionTime<s)return this.workerNodeVirtualTaskExecutionTime+=this.getWorkerNodeTaskWaitTime(r)+this.getWorkerNodeTaskRunTime(r),this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey),this.nextWorkerNodeKey=r,this.nextWorkerNodeKey}}this.interleavedWeightedRoundRobinNextWorkerNodeId()}}remove(e){return 0===this.pool.workerNodes.length?(this.resetWorkerNodeKeyProperties(),this.workerNodeId=0,this.workerNodeVirtualTaskExecutionTime=0,!0):(null!=this.nextWorkerNodeKey&&this.nextWorkerNodeKey>=e&&(this.nextWorkerNodeKey=(this.nextWorkerNodeKey-1+this.pool.workerNodes.length)%this.pool.workerNodes.length),this.workerNodeId>=e&&(this.workerNodeId=(this.workerNodeId-1+this.pool.workerNodes.length)%this.pool.workerNodes.length),!0)}reset(){return this.resetWorkerNodeKeyProperties(),this.roundId=0,this.workerNodeId=0,this.workerNodeVirtualTaskExecutionTime=0,!0}setOptions(e){super.setOptions(e),this.roundWeights=this.getRoundWeights()}update(){return!0}getRoundWeights(){return[...new Set(Object.values(this.opts.weights).slice().sort((e,t)=>e-t))]}interleavedWeightedRoundRobinNextWorkerNodeId(){0===this.pool.workerNodes.length?this.workerNodeId=0:this.roundId===this.roundWeights.length-1&&this.workerNodeId===this.pool.workerNodes.length-1?(this.roundId=0,this.workerNodeId=0):this.workerNodeId===this.pool.workerNodes.length-1?(this.roundId=this.roundId+1,this.workerNodeId=0):this.workerNodeId=this.workerNodeId+1}}class re extends Z{name=A.LEAST_BUSY;taskStatisticsRequirements=Object.freeze({elu:{...q},runTime:{aggregate:!0,average:!1,median:!1},waitTime:{aggregate:!0,average:!1,median:!1}});constructor(e,t){super(e,t),this.setTaskStatisticsRequirements(this.opts)}choose(e){return this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey),this.nextWorkerNodeKey=this.leastBusyNextWorkerNodeKey(e),this.nextWorkerNodeKey}remove(){return!0}reset(){return!0}update(){return!0}leastBusyNextWorkerNodeKey(e){if(0===e?.size)return;if(1===e?.size)return this.getSingleWorkerNodeKey(e);const t=this.pool.workerNodes.reduce((t,r,s,i)=>this.isWorkerNodeEligible(s,e)&&(-1===t||(r.usage.waitTime.aggregate??0)+(r.usage.runTime.aggregate??0)<(i[t].usage.waitTime.aggregate??0)+(i[t].usage.runTime.aggregate??0))?s:t,-1);return-1===t?void 0:t}}class se extends Z{name=A.LEAST_ELU;taskStatisticsRequirements=Object.freeze({elu:{aggregate:!0,average:!1,median:!1},runTime:{...q},waitTime:{aggregate:!0,average:!1,median:!1}});constructor(e,t){super(e,t),this.setTaskStatisticsRequirements(this.opts)}choose(e){return this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey),this.nextWorkerNodeKey=this.leastEluNextWorkerNodeKey(e),this.nextWorkerNodeKey}remove(){return!0}reset(){return!0}update(){return!0}leastEluNextWorkerNodeKey(e){if(0===e?.size)return;if(1===e?.size)return this.getSingleWorkerNodeKey(e);const t=this.pool.workerNodes.reduce((t,r,s,i)=>this.isWorkerNodeEligible(s,e)&&(-1===t||(r.usage.waitTime.aggregate??0)+(r.usage.elu.active.aggregate??0)<(i[t].usage.waitTime.aggregate??0)+(i[t].usage.elu.active.aggregate??0))?s:t,-1);return-1===t?void 0:t}}class ie extends Z{name=A.LEAST_USED;constructor(e,t){super(e,t)}choose(e){return this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey),this.nextWorkerNodeKey=this.leastUsedNextWorkerNodeKey(e),this.nextWorkerNodeKey}remove(){return!0}reset(){return!0}update(){return!0}leastUsedNextWorkerNodeKey(e){if(0===e?.size)return;if(1===e?.size)return this.getSingleWorkerNodeKey(e);const t=this.pool.workerNodes.reduce((t,r,s,i)=>this.isWorkerNodeEligible(s,e)&&(-1===t||r.usage.tasks.executing+r.usage.tasks.queued<i[t].usage.tasks.executing+i[t].usage.tasks.queued)?s:t,-1);return-1===t?void 0:t}}class oe extends Z{name=A.ROUND_ROBIN;constructor(e,t){super(e,t)}choose(e){this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey);const t=this.roundRobinNextWorkerNodeKey(e);if(null!=t&&this.isWorkerNodeEligible(t,e))return this.checkWorkerNodeKey(t)}remove(e){return 0===this.pool.workerNodes.length?this.reset():(null!=this.nextWorkerNodeKey&&this.nextWorkerNodeKey>=e&&(this.nextWorkerNodeKey=(this.nextWorkerNodeKey-1+this.pool.workerNodes.length)%this.pool.workerNodes.length,this.previousWorkerNodeKey>=e&&(this.previousWorkerNodeKey=this.nextWorkerNodeKey)),!0)}reset(){return this.resetWorkerNodeKeyProperties(),!0}update(){return!0}roundRobinNextWorkerNodeKey(e){if(null==e)return this.nextWorkerNodeKey=this.getRoundRobinNextWorkerNodeKey(),this.nextWorkerNodeKey;if(0===e.size)return;if(1===e.size){const t=this.getSingleWorkerNodeKey(e);return null!=t&&(this.nextWorkerNodeKey=t),t}const t=this.pool.workerNodes.length;for(let r=0;r<t;r++)if(this.nextWorkerNodeKey=this.getRoundRobinNextWorkerNodeKey(),e.has(this.nextWorkerNodeKey))return this.nextWorkerNodeKey}}class ne extends Z{name=A.WEIGHTED_ROUND_ROBIN;taskStatisticsRequirements=Object.freeze({elu:{...q},runTime:{aggregate:!0,average:!0,median:!1},waitTime:{aggregate:!0,average:!0,median:!1}});workerNodeVirtualTaskExecutionTime=0;constructor(e,t){super(e,t),this.setTaskStatisticsRequirements(this.opts)}choose(e){this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey);const t=this.weightedRoundRobinNextWorkerNodeKey(e);if(null!=t&&this.isWorkerNodeEligible(t,e))return this.checkWorkerNodeKey(t)}remove(e){return 0===this.pool.workerNodes.length?this.reset():(this.nextWorkerNodeKey===e&&(this.workerNodeVirtualTaskExecutionTime=0),null!=this.nextWorkerNodeKey&&this.nextWorkerNodeKey>=e&&(this.nextWorkerNodeKey=(this.nextWorkerNodeKey-1+this.pool.workerNodes.length)%this.pool.workerNodes.length,this.previousWorkerNodeKey>=e&&(this.previousWorkerNodeKey=this.nextWorkerNodeKey)),!0)}reset(){return this.resetWorkerNodeKeyProperties(),this.workerNodeVirtualTaskExecutionTime=0,!0}update(){return!0}findEligibleWorkerNodeKey(e){const t=this.pool.workerNodes.length;for(let r=0;r<t;r++)if(this.nextWorkerNodeKey=this.getRoundRobinNextWorkerNodeKey(),e.has(this.nextWorkerNodeKey))return this.nextWorkerNodeKey}weightedRoundRobinNextWorkerNodeKey(e){if(null==e){const e=this.nextWorkerNodeKey??this.previousWorkerNodeKey,t=this.opts.weights[e];return this.workerNodeVirtualTaskExecutionTime<t?(this.nextWorkerNodeKey=e,this.workerNodeVirtualTaskExecutionTime+=this.getWorkerNodeTaskWaitTime(e)+this.getWorkerNodeTaskRunTime(e)):(this.nextWorkerNodeKey=this.getRoundRobinNextWorkerNodeKey(),this.workerNodeVirtualTaskExecutionTime=0),this.nextWorkerNodeKey}if(0===e.size)return;if(1===e.size){const t=this.getSingleWorkerNodeKey(e);return null!=t&&(this.nextWorkerNodeKey=t,this.workerNodeVirtualTaskExecutionTime=0),t}const t=this.nextWorkerNodeKey??this.previousWorkerNodeKey;if(!e.has(t))return this.nextWorkerNodeKey=this.findEligibleWorkerNodeKey(e),this.workerNodeVirtualTaskExecutionTime=0,this.nextWorkerNodeKey;const r=this.opts.weights[t];return this.workerNodeVirtualTaskExecutionTime<r?(this.nextWorkerNodeKey=t,this.workerNodeVirtualTaskExecutionTime+=this.getWorkerNodeTaskWaitTime(t)+this.getWorkerNodeTaskRunTime(t)):(this.nextWorkerNodeKey=this.findEligibleWorkerNodeKey(e),this.workerNodeVirtualTaskExecutionTime=0),this.nextWorkerNodeKey}}const ae=()=>{const e=l();let t;e.every(e=>null==e.speed||0===e.speed)&&(t=(()=>{const e=performance.now(),t=performance.now()-e;return Math.trunc(15e7/t/1e3)})());let r=0;for(const s of e){null!=s.speed&&0!==s.speed||(s.speed=e.find(e=>null!=e.speed&&0!==e.speed)?.speed??t??2e3);const i=s.speed.toString().length-1;r+=1/(s.speed/10**i)*10**i}return Math.round(r/e.length)},ue=(e,t)=>{t=t??ae();const r={};for(let s=0;s<e;s++)r[s]=t;return r},he=(e,t)=>((t=structuredClone(t??{})).weights=t.weights??ue(e.info.maxSize),{elu:{median:!1},runTime:{median:!1},waitTime:{median:!1},...t}),ke=(e,t)=>{e.average&&t&&(e.average=!1,e.median=t),e.median&&!t&&(e.average=!0,e.median=t)},de=e=>{const t=Array.from(e,([e,t])=>t.strategyPolicy);return{dynamicWorkerReady:t.some(e=>e.dynamicWorkerReady),dynamicWorkerUsage:t.some(e=>e.dynamicWorkerUsage)}},le=e=>{const t=Array.from(e,([e,t])=>t.taskStatisticsRequirements);return{elu:{aggregate:t.some(e=>e.elu.aggregate),average:t.some(e=>e.elu.average),median:t.some(e=>e.elu.median)},runTime:{aggregate:t.some(e=>e.runTime.aggregate),average:t.some(e=>e.runTime.average),median:t.some(e=>e.runTime.median)},waitTime:{aggregate:t.some(e=>e.waitTime.aggregate),average:t.some(e=>e.waitTime.average),median:t.some(e=>e.waitTime.median)}}};class ce{pool;defaultWorkerChoiceStrategy;retries;workerChoiceStrategies;workerChoiceStrategiesPolicy;workerChoiceStrategiesTaskStatisticsRequirements;constructor(e,t=[A.LEAST_USED],r){this.pool=e,this.execute=this.execute.bind(this),this.defaultWorkerChoiceStrategy=t[0],this.workerChoiceStrategies=new Map;for(const e of t)this.addWorkerChoiceStrategy(e,this.pool,r);this.workerChoiceStrategiesPolicy=de(this.workerChoiceStrategies),this.workerChoiceStrategiesTaskStatisticsRequirements=le(this.workerChoiceStrategies),this.retries=((e,t)=>e.info.maxSize+Object.keys(t?.weights??ue(e.info.maxSize)).length)(this.pool,r)}execute(e=this.defaultWorkerChoiceStrategy,t){return this.executeStrategy(this.workerChoiceStrategies.get(e),t)}getPolicy(){return this.workerChoiceStrategiesPolicy}getStrategyRetries(){return Array.from(this.workerChoiceStrategies,([e,t])=>t.retriesCount).reduce((e,t)=>e+t,0)}getTaskStatisticsRequirements(){return this.workerChoiceStrategiesTaskStatisticsRequirements}remove(e){return Array.from(this.workerChoiceStrategies,([t,r])=>r.remove(e)).every(e=>e)}setDefaultWorkerChoiceStrategy(e,t){e!==this.defaultWorkerChoiceStrategy&&(this.defaultWorkerChoiceStrategy=e,this.addWorkerChoiceStrategy(e,this.pool,t))}setOptions(e){for(const t of this.workerChoiceStrategies.values())t.setOptions(e)}syncWorkerChoiceStrategies(e,t){for(const t of this.workerChoiceStrategies.keys())e.has(t)||this.removeWorkerChoiceStrategy(t);for(const r of e)this.workerChoiceStrategies.has(r)||this.addWorkerChoiceStrategy(r,this.pool,t);this.workerChoiceStrategiesPolicy=de(this.workerChoiceStrategies),this.workerChoiceStrategiesTaskStatisticsRequirements=le(this.workerChoiceStrategies)}update(e){return Array.from(this.workerChoiceStrategies,([t,r])=>r.update(e)).every(e=>e)}addWorkerChoiceStrategy(e,t,r){return this.workerChoiceStrategies.has(e)?this.workerChoiceStrategies:this.workerChoiceStrategies.set(e,((e,t,r,s)=>{switch(e){case A.FAIR_SHARE:return new(ee.bind(r))(t,s);case A.INTERLEAVED_WEIGHTED_ROUND_ROBIN:return new(te.bind(r))(t,s);case A.LEAST_BUSY:return new(re.bind(r))(t,s);case A.LEAST_ELU:return new(se.bind(r))(t,s);case A.LEAST_USED:return new(ie.bind(r))(t,s);case A.ROUND_ROBIN:return new(oe.bind(r))(t,s);case A.WEIGHTED_ROUND_ROBIN:return new(ne.bind(r))(t,s);default:throw new Error(`Worker choice strategy '${e}' is not valid`)}})(e,t,this,r))}executeStrategy(e,t){let r=e.choose(t),s=0;for(;null==r&&s<this.retries;)s++,r=e.choose(t);if(e.retriesCount=s,null==r)throw new Error(`Worker node key chosen by ${e.name} is null or undefined after ${e.retriesCount.toString()} retries (max: ${this.retries.toString()})`);return r}removeWorkerChoiceStrategy(e){return this.workerChoiceStrategies.delete(e)}}class me{size;items;maxArrayIdx;readIdx;writeIdx;constructor(e=2048){this.checkSize(e),this.readIdx=0,this.writeIdx=0,this.maxArrayIdx=e-1,this.size=0,this.items=new Float32Array(e)}clear(){this.readIdx=0,this.writeIdx=0,this.size=0}empty(){return 0===this.size}full(){return this.size===this.items.length}get(){if(this.empty())return;const e=this.items[this.readIdx];return this.readIdx=this.readIdx===this.maxArrayIdx?0:this.readIdx+1,--this.size,e}put(e){this.full()?this.readIdx=this.readIdx===this.maxArrayIdx?0:this.readIdx+1:++this.size,this.items[this.writeIdx]=e,this.writeIdx=this.writeIdx===this.maxArrayIdx?0:this.writeIdx+1}toArray(){if(this.empty())return[];const e=this.size,t=new Array(e);let r=this.readIdx;for(let s=0;s<e;s++)t[s]=this.items[r],r=r===this.maxArrayIdx?0:r+1;return t}checkSize(e){if(!Number.isSafeInteger(e))throw new TypeError(`Invalid circular buffer size: '${e.toString()}' is not an integer`);if(e<=0)throw new RangeError(`Invalid circular buffer size: ${e.toString()} <= 0`)}}class ge{capacity;nodeArray;size;start;constructor(e=2048){this.checkSize(e),this.capacity=e,this.nodeArray=new Array(this.capacity),this.clear()}clear(){if(this.size>0){let e=this.start;for(let t=0;t<this.size;t++)this.nodeArray[e]=void 0,++e,e===this.capacity&&(e=0)}this.start=0,this.size=0}delete(e){if(this.empty())return!1;let t=this.start,r=-1;for(let s=0;s<this.size;s++){if(this.nodeArray[t]?.data===e){r=s;break}++t,t===this.capacity&&(t=0)}if(-1!==r){if(r===this.size-1)return this.nodeArray[t]=void 0,--this.size,!0;let e=t;for(let t=r;t<this.size-1;t++){let t=e+1;t===this.capacity&&(t=0),this.nodeArray[e]=this.nodeArray[t],e=t}return this.nodeArray[e]=void 0,--this.size,!0}return!1}dequeue(){if(this.empty())return;const e=this.start,t=this.nodeArray[e].data;return this.nodeArray[e]=void 0,++this.start,this.start===this.capacity&&(this.start=0),--this.size,t}empty(){return 0===this.size}full(){return this.size===this.capacity}get(e){if(!(this.empty()||e<0||e>=this.size))return(e+=this.start)>=this.capacity&&(e-=this.capacity),this.nodeArray[e].data}[Symbol.iterator](){let e=this.start,t=0;return{next:()=>{if(t>=this.size)return{done:!0,value:void 0};const r=this.nodeArray[e].data;return++e,++t,e===this.capacity&&(e=0),{done:!1,value:r}}}}checkSize(e){if(!Number.isSafeInteger(e))throw new TypeError(`Invalid fixed queue size: '${e.toString()}' is not an integer`);if(e<=0)throw new RangeError(`Invalid fixed queue size: ${e.toString()} <= 0`)}}class ye extends ge{agingFactor;loadExponent;constructor(e,t=.001,r=1/1.5){super(e),this.agingFactor=t,this.loadExponent=r}enqueue(e,t){if(this.full())throw new Error("Fixed priority queue is full");t=t??0;const r=performance.now(),s=this.agingFactor*(1+((this.size+1)/this.capacity)**this.loadExponent);let i=-1,o=this.start;for(let e=0;e<this.size;e++){const e=this.nodeArray[o];if(e.priority-(r-e.timestamp)*s>t){i=o;break}++o,o===this.capacity&&(o=0)}let n=this.start+this.size;if(n>=this.capacity&&(n-=this.capacity),-1===i)i=n;else{let e=n;for(;e!==i;){const t=0===e?this.capacity-1:e-1;this.nodeArray[e]=this.nodeArray[t],e=t}}return this.nodeArray[i]={data:e,priority:t,timestamp:r},++this.size}}class we extends ge{enqueue(e,t){if(this.full())throw new Error("Fixed queue is full");let r=this.start+this.size;return r>=this.capacity&&(r-=this.capacity),this.nodeArray[r]={data:e,priority:t??0,timestamp:performance.now()},++this.size}}class fe{maxSize;size;get buckets(){return Math.trunc(this.size/this.bucketSize)}get enablePriority(){return this.priorityEnabled}set enablePriority(e){if(this.priorityEnabled===e)return;this.priorityEnabled=e;const t=Array.from(this);this.clear();for(const e of t)this.enqueue(e)}agingFactor;bucketSize;head;loadExponent;priorityEnabled;tail;constructor(e=2048,t=!1,r,s){if(!Number.isSafeInteger(e))throw new TypeError(`Invalid bucket size: '${e.toString()}' is not an integer`);if(e<=0)throw new RangeError(`Invalid bucket size: ${e.toString()} <= 0`);this.bucketSize=e,this.priorityEnabled=t,this.agingFactor=r??.001,this.loadExponent=s??p,this.clear()}clear(){this.head=this.tail=this.getPriorityQueueNode(),this.size=0,this.maxSize=0}delete(e){if(0===this.size)return!1;let t,r=this.tail;for(;null!=r;){if(r.delete(e))return r.empty()&&this.removePriorityQueueNode(r,t),--this.size,!0;t=r,r=r.next}return!1}dequeue(e){if(0===this.size)return;let t,r=this.tail;if(null!=e&&e>0){let s=1;for(;null!=r.next&&s<e;)t=r,r=r.next,++s;if(s<e||r.empty())return}else for(;!0===r?.empty()&&r!==this.head;)t=r,r=r.next;if(null==r||r.empty())return;const s=r.dequeue();return--this.size,r.empty()&&this.removePriorityQueueNode(r,t),s}enqueue(e,t){return this.head.full()&&(this.head=this.head.next=this.getPriorityQueueNode()),this.head.enqueue(e,t),++this.size,this.size>this.maxSize&&(this.maxSize=this.size),this.size}[Symbol.iterator](){let e=this.tail,t=0;return{next:()=>{for(;;){if(null==e)return{done:!0,value:void 0};for(;t>=e.size;)if(e=e.next,t=0,null==e)return{done:!0,value:void 0};const r=e.get(t);if(++t,null!=r)return{done:!1,value:r}}}}}getPriorityQueueNode(){let e;return e=this.priorityEnabled?new ye(this.bucketSize,this.agingFactor,this.loadExponent):new we(this.bucketSize),e}removePriorityQueueNode(e,t){this.head!==this.tail&&(e===this.tail&&null!=e.next?this.tail=e.next:e===this.head&&null!=t?(this.head=t,this.head.next=void 0):null!=t&&(t.next=e.next),e.next=void 0)}}class pe extends m{info;messageChannel;strategyData;tasksQueue;tasksQueueBackPressureSize;usage;worker;taskFunctionsUsage;constructor(t,r,n){var a;super(),((e,t,r)=>{if(null==e)throw new TypeError("Cannot construct a worker node without a worker type");if(!Object.values(K).includes(e))throw new TypeError(`Cannot construct a worker node with an invalid worker type '${e}'`);if(Q(t),null==r)throw new TypeError("Cannot construct a worker node without worker node options");if(!v(r))throw new TypeError("Cannot construct a worker node with invalid worker node options: must be a plain object");if(null==r.tasksQueueBackPressureSize)throw new TypeError("Cannot construct a worker node without a tasks queue back pressure size option");if(!Number.isSafeInteger(r.tasksQueueBackPressureSize))throw new TypeError("Cannot construct a worker node with a tasks queue back pressure size option that is not an integer");if(r.tasksQueueBackPressureSize<=0)throw new RangeError("Cannot construct a worker node with a tasks queue back pressure size option that is not a positive integer");if(null==r.tasksQueueBucketSize)throw new TypeError("Cannot construct a worker node without a tasks queue bucket size option");if(!Number.isSafeInteger(r.tasksQueueBucketSize))throw new TypeError("Cannot construct a worker node with a tasks queue bucket size option that is not an integer");if(r.tasksQueueBucketSize<=0)throw new RangeError("Cannot construct a worker node with a tasks queue bucket size option that is not a positive integer");if(null==r.tasksQueuePriority)throw new TypeError("Cannot construct a worker node without a tasks queue priority option");if("boolean"!=typeof r.tasksQueuePriority)throw new TypeError("Cannot construct a worker node with a tasks queue priority option that is not a boolean")})(t,r,n),this.worker=((t,r,o)=>{switch(t){case K.cluster:return e.fork(o.env);case K.thread:return new s(r,{env:i,...o.workerOptions});default:throw new Error(`Unknown worker type '${t}'`)}})(t,r,{env:n.env,workerOptions:n.workerOptions}),this.info=(a=this.worker,{backPressure:!1,backPressureStealing:!1,continuousStealing:!1,dynamic:!1,id:J(a),queuedTaskAbortion:!1,ready:!1,stealing:!1,stolen:!1,type:G(a)}),this.usage=this.initWorkerUsage(),this.info.type===K.thread&&(this.messageChannel=new o),this.tasksQueueBackPressureSize=n.tasksQueueBackPressureSize,this.tasksQueue=new fe(n.tasksQueueBucketSize,n.tasksQueuePriority,n.tasksQueueAgingFactor,n.tasksQueueLoadExponent),this.taskFunctionsUsage=new Map}clearTasksQueue(){this.tasksQueue.clear()}deleteTask(e){return this.tasksQueue.delete(e)}deleteTaskFunctionWorkerUsage(e){return this.taskFunctionsUsage.delete(e)}dequeueLastPrioritizedTask(){return this.dequeueTask(this.tasksQueue.buckets+1)}dequeueTask(e){const t=this.tasksQueue.dequeue(e);return!this.hasBackPressure()&&this.info.backPressure&&(this.info.backPressure=!1),t}enqueueTask(e){const t=this.tasksQueue.enqueue(e,e.priority);return this.hasBackPressure()&&!this.info.backPressure&&(this.info.backPressure=!0,this.emit("backPressure",{workerId:this.info.id})),t}getTaskFunctionWorkerUsage(e){if(!Array.isArray(this.info.taskFunctionsProperties))throw new Error(`Cannot get task function worker usage for task function name '${e}' when task function properties list is not yet defined`);if(Array.isArray(this.info.taskFunctionsProperties)&&this.info.taskFunctionsProperties.length<3)throw new Error(`Cannot get task function worker usage for task function name '${e}' when task function properties list has less than 3 elements`);return e===N&&(e=this.info.taskFunctionsProperties[1].name),this.taskFunctionsUsage.has(e)||this.taskFunctionsUsage.set(e,this.initTaskFunctionWorkerUsage(e)),this.taskFunctionsUsage.get(e)}registerOnceWorkerEventHandler(e,t){this.worker.once(e,t)}registerWorkerEventHandler(e,t){this.worker.on(e,t)}setTasksQueuePriority(e){this.tasksQueue.enablePriority=e}tasksQueueSize(){return this.tasksQueue.size}async terminate(){const e=new Promise(e=>{this.registerOnceWorkerEventHandler("exit",()=>{e()})});switch(this.closeMessageChannel(),this.removeAllListeners(),this.info.type){case K.cluster:this.registerOnceWorkerEventHandler("disconnect",()=>{this.worker.kill?.()}),this.worker.disconnect?.();break;case K.thread:this.worker.unref?.(),await(this.worker.terminate?.())}await e,this.worker.removeAllListeners()}closeMessageChannel(){null!=this.messageChannel&&(this.messageChannel.port1.unref(),this.messageChannel.port2.unref(),this.messageChannel.port1.close(),this.messageChannel.port2.close(),delete this.messageChannel)}hasBackPressure(){return this.tasksQueue.size>=this.tasksQueueBackPressureSize}initTaskFunctionWorkerUsage(e){const t=()=>{let t=0;for(const r of this.tasksQueue)(r.name===N&&e===this.info.taskFunctionsProperties[1].name||r.name!==N&&e===r.name)&&++t;return t};return{elu:{active:{history:new me(R)},idle:{history:new me(R)}},runTime:{history:new me(R)},tasks:{executed:0,executing:0,failed:0,get queued(){return t()},sequentiallyStolen:0,stolen:0},waitTime:{history:new me(R)}}}initWorkerUsage(){const e=()=>this.tasksQueue.size,t=()=>this.tasksQueue.maxSize;return{elu:{active:{history:new me(R)},idle:{history:new me(R)}},runTime:{history:new me(R)},tasks:{executed:0,executing:0,failed:0,get maxQueued(){return t()},get queued(){return e()},sequentiallyStolen:0,stolen:0},waitTime:{history:new me(R)}}}}class Ne{minimumNumberOfWorkers;filePath;opts;maximumNumberOfWorkers;emitter;workerNodes=[];get info(){const e=this.workerChoiceStrategiesContext?.getTaskStatisticsRequirements();return{defaultStrategy:this.opts.workerChoiceStrategy,maxSize:this.maximumNumberOfWorkers??this.minimumNumberOfWorkers,minSize:this.minimumNumberOfWorkers,ready:this.ready,started:this.started,strategyRetries:this.workerChoiceStrategiesContext?.getStrategyRetries()??0,type:this.type,version:"5.3.2",worker:this.worker,...!0===e?.runTime.aggregate&&e.waitTime.aggregate&&{utilization:b(this.utilization)},busyWorkerNodes:this.workerNodes.reduce((e,t,r)=>this.isWorkerNodeBusy(r)?e+1:e,0),executedTasks:this.workerNodes.reduce((e,t)=>e+t.usage.tasks.executed,0),executingTasks:this.workerNodes.reduce((e,t)=>e+t.usage.tasks.executing,0),failedTasks:this.workerNodes.reduce((e,t)=>e+t.usage.tasks.failed,0),idleWorkerNodes:this.workerNodes.reduce((e,t,r)=>this.isWorkerNodeIdle(r)?e+1:e,0),workerNodes:this.workerNodes.length,...this.type===w.dynamic&&{dynamicWorkerNodes:this.workerNodes.reduce((e,t)=>t.info.dynamic?e+1:e,0)},...!0===this.opts.enableTasksQueue&&{backPressure:this.backPressure,backPressureWorkerNodes:this.workerNodes.reduce((e,t,r)=>this.isWorkerNodeBackPressured(r)?e+1:e,0),maxQueuedTasks:this.workerNodes.reduce((e,t)=>e+(t.usage.tasks.maxQueued??0),0),queuedTasks:this.getQueuedTasks(),stealingWorkerNodes:this.getStealingWorkerNodes(),stolenTasks:this.workerNodes.reduce((e,t)=>e+t.usage.tasks.stolen,0)},...!0===e?.runTime.aggregate&&{runTime:{maximum:b(C(...this.workerNodes.map(e=>e.usage.runTime.maximum??Number.NEGATIVE_INFINITY))),minimum:b(O(...this.workerNodes.map(e=>e.usage.runTime.minimum??Number.POSITIVE_INFINITY))),...e.runTime.average&&{average:b(E(this.workerNodes.reduce((e,t)=>e.concat(t.usage.runTime.history.toArray()),[])))},...e.runTime.median&&{median:b(S(this.workerNodes.reduce((e,t)=>e.concat(t.usage.runTime.history.toArray()),[])))}}},...!0===e?.waitTime.aggregate&&{waitTime:{maximum:b(C(...this.workerNodes.map(e=>e.usage.waitTime.maximum??Number.NEGATIVE_INFINITY))),minimum:b(O(...this.workerNodes.map(e=>e.usage.waitTime.minimum??Number.POSITIVE_INFINITY))),...e.waitTime.average&&{average:b(E(this.workerNodes.reduce((e,t)=>e.concat(t.usage.waitTime.history.toArray()),[])))},...e.waitTime.median&&{median:b(S(this.workerNodes.reduce((e,t)=>e.concat(t.usage.waitTime.history.toArray()),[])))}}},...!0===e?.elu.aggregate&&{elu:{active:{maximum:b(C(...this.workerNodes.map(e=>e.usage.elu.active.maximum??Number.NEGATIVE_INFINITY))),minimum:b(O(...this.workerNodes.map(e=>e.usage.elu.active.minimum??Number.POSITIVE_INFINITY))),...e.elu.average&&{average:b(E(this.workerNodes.reduce((e,t)=>e.concat(t.usage.elu.active.history.toArray()),[])))},...e.elu.median&&{median:b(S(this.workerNodes.reduce((e,t)=>e.concat(t.usage.elu.active.history.toArray()),[])))}},idle:{maximum:b(C(...this.workerNodes.map(e=>e.usage.elu.idle.maximum??Number.NEGATIVE_INFINITY))),minimum:b(O(...this.workerNodes.map(e=>e.usage.elu.idle.minimum??Number.POSITIVE_INFINITY))),...e.elu.average&&{average:b(E(this.workerNodes.reduce((e,t)=>e.concat(t.usage.elu.idle.history.toArray()),[])))},...e.elu.median&&{median:b(S(this.workerNodes.reduce((e,t)=>e.concat(t.usage.elu.idle.history.toArray()),[])))}},utilization:{average:b(E(this.workerNodes.map(e=>e.usage.elu.utilization??0))),median:b(S(this.workerNodes.map(e=>e.usage.elu.utilization??0)))}}}}}destroying;promiseResponseMap=new Map;started;starting;workerChoiceStrategiesContext;backPressureEventEmitted;busyEventEmitted;readyEventEmitted;startingMinimumNumberOfWorkers;startTimestamp;taskFunctions;get ready(){return!!this.started&&this.workerNodes.reduce((e,t)=>!t.info.dynamic&&t.info.ready?e+1:e,0)>=this.minimumNumberOfWorkers}get utilization(){if(null==this.startTimestamp)return 0;const e=(y.now()-this.startTimestamp)*(this.maximumNumberOfWorkers??this.minimumNumberOfWorkers);if(!Number.isFinite(e)||e<=0)return 0;return(this.workerNodes.reduce((e,t)=>e+(t.usage.runTime.aggregate??0),0)+this.workerNodes.reduce((e,t)=>e+(t.usage.waitTime.aggregate??0),0))/e}constructor(e,t,r,s){if(this.minimumNumberOfWorkers=e,this.filePath=t,this.opts=r,this.maximumNumberOfWorkers=s,!this.isMain())throw new Error("Cannot start a pool from a worker with the same type as the pool");this.checkPoolType(),Q(this.filePath),this.checkMinimumNumberOfWorkers(this.minimumNumberOfWorkers),this.checkPoolOptions(this.opts),this.chooseWorkerNode=this.chooseWorkerNode.bind(this),this.executeTask=this.executeTask.bind(this),this.enqueueTask=this.enqueueTask.bind(this),!0===this.opts.enableEvents&&this.initEventEmitter(),this.workerChoiceStrategiesContext=new ce(this,[this.opts.workerChoiceStrategy],this.opts.workerChoiceStrategyOptions),this.setupHook(),this.taskFunctions=new Map,this.started=!1,this.starting=!1,this.destroying=!1,this.readyEventEmitted=!1,this.busyEventEmitted=!1,this.backPressureEventEmitted=!1,this.startingMinimumNumberOfWorkers=!1,!0===this.opts.startWorkers&&this.start()}async addTaskFunction(e,t){if("string"!=typeof e)throw new TypeError("name argument must be a string");if("string"==typeof e&&0===e.trim().length)throw new TypeError("name argument must not be an empty string");if("function"==typeof t&&(t={taskFunction:t}),"function"!=typeof t.taskFunction)throw new TypeError("taskFunction property must be a function");D(t.priority),B(t.strategy),_(t.workerNodeKeys,this.maximumNumberOfWorkers??this.minimumNumberOfWorkers);const r=await this.sendTaskFunctionOperationToWorkers({taskFunction:t.taskFunction.toString(),taskFunctionOperation:"add",taskFunctionProperties:P(e,t)});this.taskFunctions.set(e,t),this.workerChoiceStrategiesContext?.syncWorkerChoiceStrategies(this.getWorkerChoiceStrategies());for(const e of this.workerNodes.keys())this.sendStatisticsMessageToWorker(e);return r}async destroy(){if(!this.started)throw new Error("Cannot destroy an already destroyed pool");if(this.starting)throw new Error("Cannot destroy an starting pool");if(this.destroying)throw new Error("Cannot destroy an already destroying pool");this.destroying=!0;try{await Promise.allSettled(this.workerNodes.map(async(e,t)=>{try{await this.destroyWorkerNode(t)}catch(e){this.emitter?.emit(f.error,e)}}))}finally{delete this.startTimestamp,this.destroying=!1,this.started=!1,null!=this.emitter&&(this.emitter.listenerCount(f.destroy)>0&&this.emitter.emit(f.destroy,this.info),this.emitter.emitDestroy(),this.readyEventEmitted=!1)}}enableTasksQueue(e,t){!0!==this.opts.enableTasksQueue||e||(this.unsetTaskStealing(),this.unsetTasksStealingOnBackPressure(),this.flushTasksQueues()),this.opts.enableTasksQueue=e,this.setTasksQueueOptions(t)}async execute(e,t,r,s){if(!this.started)throw new Error("Cannot execute a task on not started pool");if(this.destroying)throw new Error("Cannot execute a task on destroying pool");if(null!=t&&"string"!=typeof t)throw new TypeError("name argument must be a string");if(null!=t&&"string"==typeof t&&0===t.trim().length)throw new TypeError("name argument must not be an empty string");if(null!=r&&!(r instanceof AbortSignal))throw new TypeError("abortSignal argument must be an AbortSignal");if(null!=s&&!Array.isArray(s))throw new TypeError("transferList argument must be an array");return await this.internalExecute(e,t,r,s)}hasTaskFunction(e){return this.listTaskFunctionsProperties().some(t=>t.name===e)}listTaskFunctionsProperties(){for(const e of this.workerNodes)if(Array.isArray(e.info.taskFunctionsProperties)&&e.info.taskFunctionsProperties.length>0)return e.info.taskFunctionsProperties;return[]}async mapExecute(e,t,r,s){if(!this.started)throw new Error("Cannot execute task(s) on not started pool");if(this.destroying)throw new Error("Cannot execute task(s) on destroying pool");if(null==e)throw new TypeError("data argument must be a defined iterable");if("function"!=typeof e[Symbol.iterator])throw new TypeError("data argument must be an iterable");if(null!=t&&"string"!=typeof t)throw new TypeError("name argument must be a string");if(null!=t&&"string"==typeof t&&0===t.trim().length)throw new TypeError("name argument must not be an empty string");if(Array.isArray(e)||(e=[...e]),null!=r){if("function"!=typeof r[Symbol.iterator])throw new TypeError("abortSignals argument must be an iterable");for(const e of r)if(!(e instanceof AbortSignal))throw new TypeError("abortSignals argument must be an iterable of AbortSignal");if(Array.isArray(r)||(r=[...r]),e.length!==r.length)throw new Error("data and abortSignals arguments must have the same length")}if(null!=s&&!Array.isArray(s))throw new TypeError("transferList argument must be an array");const i=Array.from({length:e.length},(t,s)=>[e[s],null!=r?r[s]:void 0]);return await Promise.all(i.map(([e,r])=>this.internalExecute(e,t,r,s)))}async removeTaskFunction(e){if(!this.taskFunctions.has(e))throw new Error("Cannot remove a task function not handled on the pool side");const t=await this.sendTaskFunctionOperationToWorkers({taskFunctionOperation:"remove",taskFunctionProperties:P(e,this.taskFunctions.get(e))});for(const t of this.workerNodes)t.deleteTaskFunctionWorkerUsage(e);this.taskFunctions.delete(e),this.workerChoiceStrategiesContext?.syncWorkerChoiceStrategies(this.getWorkerChoiceStrategies());for(const e of this.workerNodes.keys())this.sendStatisticsMessageToWorker(e);return t}async setDefaultTaskFunction(e){return await this.sendTaskFunctionOperationToWorkers({taskFunctionOperation:"default",taskFunctionProperties:P(e,this.taskFunctions.get(e))})}setTasksQueueOptions(e){!0===this.opts.enableTasksQueue?(L(e),this.opts.tasksQueueOptions=this.buildTasksQueueOptions(e),this.setTasksQueueSize(this.opts.tasksQueueOptions.size),!0===this.opts.tasksQueueOptions.taskStealing?(this.unsetTaskStealing(),this.setTaskStealing()):this.unsetTaskStealing(),!0===this.opts.tasksQueueOptions.tasksStealingOnBackPressure?(this.unsetTasksStealingOnBackPressure(),this.setTasksStealingOnBackPressure()):this.unsetTasksStealingOnBackPressure()):null!=this.opts.tasksQueueOptions&&delete this.opts.tasksQueueOptions}setWorkerChoiceStrategy(e,t){let r=!1;if(B(e),null!=t&&(r=!this.setWorkerChoiceStrategyOptions(t)),e!==this.opts.workerChoiceStrategy&&(this.opts.workerChoiceStrategy=e,this.workerChoiceStrategiesContext?.setDefaultWorkerChoiceStrategy(this.opts.workerChoiceStrategy,this.opts.workerChoiceStrategyOptions),r=!0),r){this.workerChoiceStrategiesContext?.syncWorkerChoiceStrategies(this.getWorkerChoiceStrategies(),this.opts.workerChoiceStrategyOptions);for(const e of this.workerNodes.keys())this.sendStatisticsMessageToWorker(e)}}setWorkerChoiceStrategyOptions(e){if(this.checkValidWorkerChoiceStrategyOptions(e),null!=e){this.opts.workerChoiceStrategyOptions={...this.opts.workerChoiceStrategyOptions,...e},this.workerChoiceStrategiesContext?.setOptions(this.opts.workerChoiceStrategyOptions),this.workerChoiceStrategiesContext?.syncWorkerChoiceStrategies(this.getWorkerChoiceStrategies(),this.opts.workerChoiceStrategyOptions);for(const e of this.workerNodes.keys())this.sendStatisticsMessageToWorker(e);return!0}return!1}start(){if(this.started)throw new Error("Cannot start an already started pool");if(this.starting)throw new Error("Cannot start an already starting pool");if(this.destroying)throw new Error("Cannot start a destroying pool");this.starting=!0,this.startMinimumNumberOfWorkers(),this.startTimestamp=y.now(),this.starting=!1,this.started=!0}afterTaskExecutionHook(e,t){let r=!1;if(null!=this.workerNodes[e]?.usage){const s=this.workerNodes[e].usage;H(s,t),j(this.workerChoiceStrategiesContext,s,t),Y(this.workerChoiceStrategiesContext,s,t),r=!0}if(this.shallUpdateTaskFunctionWorkerUsage(e)&&null!=t.taskPerformance?.name&&null!=this.workerNodes[e].getTaskFunctionWorkerUsage(t.taskPerformance.name)){const s=this.workerNodes[e].getTaskFunctionWorkerUsage(t.taskPerformance.name);H(s,t),j(this.workerChoiceStrategiesContext,s,t),Y(this.workerChoiceStrategiesContext,s,t),r=!0}r&&this.workerChoiceStrategiesContext?.update(e)}afterWorkerNodeSetup(e){this.registerWorkerMessageListener(e,this.workerMessageListener),this.sendStartupMessageToWorker(e),this.sendStatisticsMessageToWorker(e),!0===this.opts.enableTasksQueue&&(!0===this.opts.tasksQueueOptions?.taskStealing&&this.workerNodes[e].on("idle",this.handleWorkerNodeIdleEvent),!0===this.opts.tasksQueueOptions?.tasksStealingOnBackPressure&&this.workerNodes[e].on("backPressure",this.handleWorkerNodeBackPressureEvent)),this.workerNodes[e].on("abortTask",this.abortTask)}beforeTaskExecutionHook(e,t){if(null!=this.workerNodes[e]?.usage){const r=this.workerNodes[e].usage;++r.tasks.executing,V(this.workerChoiceStrategiesContext,r,t)}if(this.shallUpdateTaskFunctionWorkerUsage(e)&&null!=this.workerNodes[e].getTaskFunctionWorkerUsage(t.name)){const r=this.workerNodes[e].getTaskFunctionWorkerUsage(t.name);++r.tasks.executing,V(this.workerChoiceStrategiesContext,r,t)}}createAndSetupDynamicWorkerNode(){const e=this.createAndSetupWorkerNode();if(this.registerWorkerMessageListener(e,e=>{if(this.destroying)return;this.checkMessageWorkerId(e);const t=this.getWorkerNodeKeyByWorkerId(e.workerId);(x(X.HARD,e.kill)||x(X.SOFT,e.kill)&&this.isWorkerNodeIdle(t)&&!this.isWorkerNodeStealing(t))&&this.destroyWorkerNode(t).catch(e=>{this.emitter?.emit(f.error,e)})}),this.sendToWorker(e,{checkActive:!0}),this.taskFunctions.size>0)for(const[t,r]of this.taskFunctions)this.sendTaskFunctionOperationToWorker(e,{taskFunction:r.taskFunction.toString(),taskFunctionOperation:"add",taskFunctionProperties:P(t,r)}).catch(e=>{this.emitter?.emit(f.error,e)});const t=this.workerNodes[e];return t.info.dynamic=!0,!0===this.workerChoiceStrategiesContext?.getPolicy().dynamicWorkerReady&&(t.info.ready=!0),this.initWorkerNodeUsage(t),this.checkAndEmitDynamicWorkerCreationEvents(),e}createAndSetupWorkerNode(){const e=this.createWorkerNode();e.registerWorkerEventHandler("online",this.opts.onlineHandler??T),e.registerWorkerEventHandler("message",this.opts.messageHandler??T),e.registerWorkerEventHandler("error",this.opts.errorHandler??T),e.registerOnceWorkerEventHandler("error",t=>{e.info.ready=!1,this.emitter?.emit(f.error,t),this.started&&!this.destroying&&(!0===this.opts.restartWorkerOnError&&(e.info.dynamic?this.createAndSetupDynamicWorkerNode():this.startingMinimumNumberOfWorkers||this.startMinimumNumberOfWorkers(!0)),!0===this.opts.enableTasksQueue&&this.redistributeQueuedTasks(this.workerNodes.indexOf(e))),e?.terminate().catch(e=>{this.emitter?.emit(f.error,e)})}),e.registerWorkerEventHandler("exit",this.opts.exitHandler??T),e.registerOnceWorkerEventHandler("exit",()=>{this.removeWorkerNode(e),!this.started||this.startingMinimumNumberOfWorkers||this.destroying||this.startMinimumNumberOfWorkers(!0)});const t=this.addWorkerNode(e);return this.afterWorkerNodeSetup(t),t}async destroyWorkerNode(e){this.flagWorkerNodeAsNotReady(e);const t=this.flushTasksQueue(e),r=this.workerNodes[e];await(async(e,t,r,s,i=!0)=>await new Promise((o,n)=>{let a=0;if(0===r)return void o(a);const u=()=>{++a,a>=r&&(null!=h&&clearTimeout(h),e.off(t,u),o(a))},h=s>=0?setTimeout(()=>{e.off(t,u),i?n(new Error(`Timed out after ${s.toString()}ms waiting for ${r.toString()} '${t}' events. Received ${a.toString()} events`)):o(a)},s):void 0;switch(t){case"backPressure":case"idle":case"taskFinished":e.on(t,u);break;default:null!=h&&clearTimeout(h),n(new Error("Invalid worker node event"))}}))(r,"taskFinished",t,this.opts.tasksQueueOptions?.tasksFinishedTimeout??M(this.maximumNumberOfWorkers??this.minimumNumberOfWorkers).tasksFinishedTimeout,!1),await this.sendKillMessageToWorker(e),await r.terminate()}flagWorkerNodeAsNotReady(e){const t=this.getWorkerInfo(e);null!=t&&(t.ready=!1)}flushTasksQueue(e){let t=0;for(;this.tasksQueueSize(e)>0;)this.executeTask(e,this.dequeueTask(e)),++t;return this.workerNodes[e].clearTasksQueue(),t}getWorkerInfo(e){return this.workerNodes[e]?.info}internalBackPressure(){return 0!==this.workerNodes.length&&this.workerNodes.reduce((e,t,r)=>this.isWorkerNodeBackPressured(r)?e+1:e,0)===this.workerNodes.length}internalBusy(){return 0!==this.workerNodes.length&&this.workerNodes.reduce((e,t,r)=>this.isWorkerNodeBusy(r)?e+1:e,0)===this.workerNodes.length}setupHook(){}workerMessageListener=e=>{const{kill:t,ready:r,taskFunctionsProperties:s,taskId:i,workerId:o}=e,n=null!=r&&null!=s;if(!(this.destroying&&n||null!=t))if(this.checkMessageWorkerId(e),n)this.handleWorkerReadyResponse(e);else if(null!=s){const e=this.getWorkerNodeKeyByWorkerId(o),t=this.getWorkerInfo(e);null!=t&&(t.taskFunctionsProperties=s,this.sendStatisticsMessageToWorker(e),this.setTasksQueuePriority(e))}else null!=i&&this.handleTaskExecutionResponse(e)};abortTask=e=>{if(!this.started)return;const{taskId:t,workerId:r}=e,s=this.promiseResponseMap.get(t);if(null==s)return;const{abortSignal:i,reject:o}=s;if(!1===i?.aborted)return;const n=this.getWorkerNodeKeyByWorkerId(r),a=this.workerNodes[n];if(a.info.ready){if(!0===this.opts.enableTasksQueue)for(const e of a.tasksQueue){const{abortable:r,name:s}=e;if(t===e.taskId&&!0===r)return a.info.queuedTaskAbortion=!0,a.deleteTask(e),this.promiseResponseMap.delete(t),a.info.queuedTaskAbortion=!1,void o(this.getAbortError(s,t))}this.sendToWorker(n,{taskId:t,taskOperation:"abort"})}};addWorkerNode(e){this.workerNodes.push(e);const t=this.workerNodes.indexOf(e);if(-1===t)throw new Error("Worker added not found in worker nodes");return t}buildTasksQueueOptions(e){return{...M(this.maximumNumberOfWorkers??this.minimumNumberOfWorkers),...this.opts.tasksQueueOptions,...e}}cannotStealTask(){return!this.started||this.destroying||this.workerNodes.length<=1||0===this.getQueuedTasks()}checkAndEmitReadyEvent(){null!=this.emitter&&!this.readyEventEmitted&&this.ready&&(this.emitter.listenerCount(f.ready)>0&&this.emitter.emit(f.ready,this.info),this.readyEventEmitted=!0)}checkAndEmitTaskDequeuingEvents(){null!=this.emitter&&this.backPressureEventEmitted&&!this.backPressure&&(this.emitter.listenerCount(f.backPressureEnd)>0&&this.emitter.emit(f.backPressureEnd,this.info),this.backPressureEventEmitted=!1)}checkAndEmitTaskExecutionEvents(){null!=this.emitter&&!this.busyEventEmitted&&this.busy&&(this.emitter.listenerCount(f.busy)>0&&this.emitter.emit(f.busy,this.info),this.busyEventEmitted=!0)}checkAndEmitTaskExecutionFinishedEvents(){null!=this.emitter&&this.busyEventEmitted&&!this.busy&&(this.emitter.listenerCount(f.busyEnd)>0&&this.emitter.emit(f.busyEnd,this.info),this.busyEventEmitted=!1)}checkAndEmitTaskQueuingEvents(){null!=this.emitter&&!this.backPressureEventEmitted&&this.backPressure&&(this.emitter.listenerCount(f.backPressure)>0&&this.emitter.emit(f.backPressure,this.info),this.backPressureEventEmitted=!0)}checkMessageWorkerId(e){if(null==e.workerId)throw new Error(`Worker message '${JSON.stringify(e)}' received without worker id`);if(-1===this.getWorkerNodeKeyByWorkerId(e.workerId))throw new Error(`Worker message '${JSON.stringify(e)}' received from unknown worker ${e.workerId.toString()}`)}checkMinimumNumberOfWorkers(e){if(null==e)throw new Error("Cannot instantiate a pool without specifying the number of workers");if(!Number.isSafeInteger(e))throw new TypeError("Cannot instantiate a pool with a non safe integer number of workers");if(e<0)throw new RangeError("Cannot instantiate a pool with a negative number of workers");if(this.type===w.fixed&&0===e)throw new RangeError("Cannot instantiate a fixed pool with zero worker")}checkPoolOptions(e){if(!v(e))throw new TypeError("Invalid pool options: must be a plain object");this.opts.startWorkers=e.startWorkers??!0,B(e.workerChoiceStrategy),this.opts.workerChoiceStrategy=e.workerChoiceStrategy??A.LEAST_USED,this.checkValidWorkerChoiceStrategyOptions(e.workerChoiceStrategyOptions),null!=e.workerChoiceStrategyOptions&&(this.opts.workerChoiceStrategyOptions=e.workerChoiceStrategyOptions),this.opts.restartWorkerOnError=e.restartWorkerOnError??!0,this.opts.enableEvents=e.enableEvents??!0,this.opts.enableTasksQueue=e.enableTasksQueue??!1,this.opts.enableTasksQueue&&(L(e.tasksQueueOptions),this.opts.tasksQueueOptions=this.buildTasksQueueOptions(e.tasksQueueOptions))}checkPoolType(){if(this.type===w.fixed&&null!=this.maximumNumberOfWorkers)throw new Error("Cannot instantiate a fixed pool with a maximum number of workers defined at initialization")}checkValidWorkerChoiceStrategyOptions(e){if(null!=e&&!v(e))throw new TypeError("Invalid worker choice strategy options: must be a plain object");if(null!=e?.weights&&Object.keys(e.weights).length!==(this.maximumNumberOfWorkers??this.minimumNumberOfWorkers))throw new Error("Invalid worker choice strategy options: must have a weight for each worker node");if(null!=e?.measurement&&!Object.values(z).includes(e.measurement))throw new Error(`Invalid worker choice strategy options: invalid measurement '${e.measurement}'`)}chooseWorkerNode(e){const t=this.getTaskFunctionWorkerNodeKeysSet(e);if(null!=t){const e=this.maximumNumberOfWorkers??this.minimumNumberOfWorkers,r=C(...t)+1;for(;this.started&&!this.destroying&&this.workerNodes.length<r&&this.workerNodes.length<e;)this.createAndSetupDynamicWorkerNode()}else if(this.shallCreateDynamicWorker()){const e=this.createAndSetupDynamicWorkerNode();if(!0===this.workerChoiceStrategiesContext?.getPolicy().dynamicWorkerUsage)return e}return this.workerChoiceStrategiesContext.execute(this.getTaskFunctionWorkerChoiceStrategy(e),t)}createWorkerNode(){const e=new pe(this.worker,this.filePath,{env:this.opts.env,tasksQueueAgingFactor:this.opts.tasksQueueOptions?.agingFactor,tasksQueueBackPressureSize:this.opts.tasksQueueOptions?.size??M(this.maximumNumberOfWorkers??this.minimumNumberOfWorkers).size,tasksQueueBucketSize:2048,tasksQueueLoadExponent:this.opts.tasksQueueOptions?.loadExponent,tasksQueuePriority:this.getTasksQueuePriority(),workerOptions:this.opts.workerOptions});return this.starting&&(e.info.ready=!0),e}dequeueTask(e){const t=this.workerNodes[e].dequeueTask();return this.checkAndEmitTaskDequeuingEvents(),t}enqueueTask(e,t){const r=this.workerNodes[e].enqueueTask(t);return this.checkAndEmitTaskQueuingEvents(),r}executeTask(e,t){const{transferList:r}=t;this.beforeTaskExecutionHook(e,t),this.sendToWorker(e,t,r),this.checkAndEmitTaskExecutionEvents()}flushTasksQueues(){for(const e of this.workerNodes.keys())this.flushTasksQueue(e)}getAbortError=(e,t)=>{const r=this.promiseResponseMap.get(t)?.abortSignal?.reason;return r instanceof Error?r:"string"==typeof r?new Error(r):new Error(`Task '${e}' id '${t}' aborted`)};getQueuedTasks(){return this.workerNodes.reduce((e,t)=>e+t.usage.tasks.queued,0)}getStealingWorkerNodes(){return this.workerNodes.reduce((e,t,r)=>this.isWorkerNodeStealing(r)?e+1:e,0)}getTaskFunctionWorkerChoiceStrategy=e=>{e=e??N;const t=this.listTaskFunctionsProperties();return e===N&&(e=t[1]?.name),t.find(t=>t.name===e)?.strategy};getTaskFunctionWorkerNodeKeysSet=e=>{e=e??N;const t=this.listTaskFunctionsProperties();e===N&&(e=t[1]?.name);const r=t.find(t=>t.name===e)?.workerNodeKeys;return null!=r?new Set(r):void 0};getTasksQueuePriority(){return this.listTaskFunctionsProperties().some(e=>null!=e.priority)}getWorkerChoiceStrategies=()=>new Set([this.opts.workerChoiceStrategy,...this.listTaskFunctionsProperties().map(e=>e.strategy).filter(e=>null!=e)]);getWorkerNodeKeyByWorkerId(e){return this.workerNodes.findIndex(t=>t.info.id===e)}getWorkerNodeTaskFunctionPriority=(e,t)=>{const r=this.getWorkerInfo(e);if(null!=r)return(t=t??N)===N&&(t=r.taskFunctionsProperties?.[1]?.name),r.taskFunctionsProperties?.find(e=>e.name===t)?.priority};getWorkerNodeTaskFunctionWorkerChoiceStrategy=(e,t)=>{const r=this.getWorkerInfo(e);if(null!=r)return(t=t??N)===N&&(t=r.taskFunctionsProperties?.[1]?.name),r.taskFunctionsProperties?.find(e=>e.name===t)?.strategy};handleTask(e,t){this.shallExecuteTask(e)?this.executeTask(e,t):this.enqueueTask(e,t)}handleTaskExecutionResponse(e){const{data:t,taskId:r,workerError:s}=e,i=this.promiseResponseMap.get(r);if(null!=i){const{asyncResource:o,reject:n,resolve:a,workerNodeKey:u}=i,h=this.workerNodes[u];if(null!=s){this.emitter?.emit(f.taskError,s);const e=this.handleWorkerError(r,s);null!=o?o.runInAsyncScope(n,this.emitter,e):n(e)}else null!=o?o.runInAsyncScope(a,this.emitter,t):a(t);o?.emitDestroy(),this.afterTaskExecutionHook(u,e),queueMicrotask(()=>{h?.emit("taskFinished",r),this.promiseResponseMap.delete(r),this.checkAndEmitTaskExecutionFinishedEvents(),!0!==this.opts.enableTasksQueue||this.destroying||(!this.isWorkerNodeBusy(u)&&this.tasksQueueSize(u)>0&&this.executeTask(u,this.dequeueTask(u)),this.isWorkerNodeIdle(u)&&h.emit("idle",{workerNodeKey:u})),this.shallCreateDynamicWorker()&&this.createAndSetupDynamicWorkerNode()})}}handleWorkerError=(e,t)=>{const{aborted:r,error:s,message:i,name:o,stack:n}=t;if(r)return this.getAbortError(o,e);if(null!=s)return s;const a=new Error(i);return a.stack=n,a};handleWorkerNodeBackPressureEvent=e=>{if(this.cannotStealTask()||this.backPressure||this.isStealingRatioReached())return;if(this.opts.tasksQueueOptions.size<=1)return;const{workerId:t}=e,r=this.getWorkerNodeKeyByWorkerId(t),s=this.workerNodes[r];if(null==s)return;const i=this.workerNodes.slice().sort((e,t)=>e.usage.tasks.queued-t.usage.tasks.queued);for(const e of i){if(0===s.usage.tasks.queued)break;if(e!==s&&!e.info.backPressureStealing&&e.usage.tasks.queued<this.opts.tasksQueueOptions.size-1){const t=this.workerNodes.indexOf(e);e.info.backPressureStealing=!0,this.stealTask(s,t),e.info.backPressureStealing=!1}}};handleWorkerNodeIdleEvent=(e,t)=>{const{workerNodeKey:r}=e;if(null==r)throw new Error("WorkerNode event detail 'workerNodeKey' property must be defined");const s=this.workerNodes[r];if(null==s)return;if(!s.info.continuousStealing&&(this.cannotStealTask()||this.isStealingRatioReached()))return;const i=s.usage.tasks;if(s.info.continuousStealing&&!this.isWorkerNodeIdle(r))return s.info.continuousStealing=!1,void(i.sequentiallyStolen>0&&this.resetTaskSequentiallyStolenStatisticsWorkerUsage(r,t?.name));s.info.continuousStealing=!0;const o=this.workerNodeStealTask(r);this.updateTaskSequentiallyStolenStatisticsWorkerUsage(r,o?.name,t?.name),(async e=>{await new Promise(t=>{setTimeout(t,e)})})(((e=0,t=100)=>{const r=2**e*t;return r+.2*r*F()})(i.sequentiallyStolen)).then(()=>{this.handleWorkerNodeIdleEvent(e,o)}).catch(e=>{this.emitter?.emit(f.error,e)})};handleWorkerReadyResponse(e){const{ready:t,taskFunctionsProperties:r,workerId:s}=e;if(null==t||!t)throw new Error(`Worker ${s?.toString()} failed to initialize`);const i=this.maximumNumberOfWorkers??this.minimumNumberOfWorkers;for(const e of r??[])_(e.workerNodeKeys,i);const o=this.getWorkerNodeKeyByWorkerId(s),n=this.workerNodes[o];n.info.ready=t,n.info.taskFunctionsProperties=r,this.sendStatisticsMessageToWorker(o),this.setTasksQueuePriority(o),this.checkAndEmitReadyEvent()}initEventEmitter(){this.emitter=new g({name:`poolifier:${this.type}-${this.worker}-pool`})}initWorkerNodeUsage(e){const t=this.workerChoiceStrategiesContext?.getTaskStatisticsRequirements();!0===t?.runTime.aggregate&&(e.usage.runTime.aggregate=O(...this.workerNodes.map(e=>e.usage.runTime.aggregate??Number.POSITIVE_INFINITY))),!0===t?.waitTime.aggregate&&(e.usage.waitTime.aggregate=O(...this.workerNodes.map(e=>e.usage.waitTime.aggregate??Number.POSITIVE_INFINITY))),!0===t?.elu.aggregate&&(e.usage.elu.active.aggregate=O(...this.workerNodes.map(e=>e.usage.elu.active.aggregate??Number.POSITIVE_INFINITY)))}async internalExecute(e,t,r,s){return await new Promise((i,o)=>{const n=y.now(),a=this.chooseWorkerNode(t),u={abortable:null!=r,data:e??{},name:t??N,priority:this.getWorkerNodeTaskFunctionPriority(a,t),strategy:this.getWorkerNodeTaskFunctionWorkerChoiceStrategy(a,t),taskId:k(),timestamp:n,transferList:s};r?.addEventListener("abort",()=>{this.workerNodes[a]?.emit("abortTask",{taskId:u.taskId,workerId:this.getWorkerInfo(a).id})},{once:!0}),this.promiseResponseMap.set(u.taskId,{reject:o,resolve:i,workerNodeKey:a,...null!=this.emitter&&{asyncResource:new c("poolifier:task",{requireManualDestroy:!0,triggerAsyncId:this.emitter.asyncId})},abortSignal:r}),!1===this.opts.enableTasksQueue||!0===this.opts.enableTasksQueue&&this.shallExecuteTask(a)?this.executeTask(a,u):this.enqueueTask(a,u)})}isStealingRatioReached=()=>0===this.opts.tasksQueueOptions?.tasksStealingRatio||this.getStealingWorkerNodes()>Math.ceil(this.workerNodes.length*this.opts.tasksQueueOptions.tasksStealingRatio);isWorkerNodeBackPressured(e){const t=this.workerNodes[e];return null!=t&&(t.info.ready&&t.info.backPressure)}isWorkerNodeBusy(e){const t=this.workerNodes[e];return null!=t&&(!0===this.opts.enableTasksQueue?t.info.ready&&t.usage.tasks.executing>=this.opts.tasksQueueOptions.concurrency:t.info.ready&&t.usage.tasks.executing>0)}isWorkerNodeIdle(e){const t=this.workerNodes[e];return null!=t&&(!0===this.opts.enableTasksQueue?t.info.ready&&0===t.usage.tasks.executing&&0===this.tasksQueueSize(e):t.info.ready&&0===t.usage.tasks.executing)}isWorkerNodeStealing(e){const t=this.workerNodes[e];return null!=t&&(t.info.ready&&(t.info.continuousStealing||t.info.backPressureStealing))}redistributeQueuedTasks(e){if(-1!==e&&!this.cannotStealTask())for(;this.tasksQueueSize(e)>0;){const t=this.workerNodes.reduce((t,r,s,i)=>s!==e&&r.info.ready&&(-1===t||r.usage.tasks.queued<i[t].usage.tasks.queued)?s:t,-1);if(-1===t)break;this.handleTask(t,this.dequeueTask(e))}}removeWorkerNode(e){const t=this.workerNodes.indexOf(e);-1!==t&&(this.workerNodes.splice(t,1),this.workerChoiceStrategiesContext?.remove(t),e.info.dynamic&&this.checkAndEmitDynamicWorkerDestructionEvents())}resetTaskSequentiallyStolenStatisticsWorkerUsage(e,t){const r=this.workerNodes[e];null!=r?.usage&&(r.usage.tasks.sequentiallyStolen=0),null!=t&&this.shallUpdateTaskFunctionWorkerUsage(e)&&null!=r.getTaskFunctionWorkerUsage(t)&&(r.getTaskFunctionWorkerUsage(t).tasks.sequentiallyStolen=0)}async sendKillMessageToWorker(e,t=1e3){let r,s;try{await new Promise((i,o)=>{r=t>=0?setTimeout(()=>{i()},t):void 0,s=t=>{0!==this.workerNodes.length&&null!=this.workerNodes[e]?"success"===t.kill?i():"failure"===t.kill&&o(new Error(`Kill message handling failed on worker ${t.workerId?.toString()}`)):i()},this.registerWorkerMessageListener(e,s),this.sendToWorker(e,{kill:!0})})}finally{null!=r&&clearTimeout(r),null!=s&&this.deregisterWorkerMessageListener(e,s)}}sendStatisticsMessageToWorker(e){const t=this.workerChoiceStrategiesContext?.getTaskStatisticsRequirements();this.sendToWorker(e,{statistics:{elu:t?.elu.aggregate??!1,runTime:t?.runTime.aggregate??!1}})}async sendTaskFunctionOperationToWorker(e,t){let r;try{return await new Promise((s,i)=>{r=t=>{this.checkMessageWorkerId(t);const r=this.getWorkerInfo(e)?.id;if(null!=t.taskFunctionOperationStatus&&t.workerId===r){if(t.taskFunctionOperationStatus)return void s(!0);i(new Error(`Task function operation '${t.taskFunctionOperation?.toString()}' failed on worker ${t.workerId?.toString()} with error: '${t.workerError?.message}'`))}},this.registerWorkerMessageListener(e,r),this.sendToWorker(e,t)})}finally{null!=r&&this.deregisterWorkerMessageListener(e,r)}}async sendTaskFunctionOperationToWorkers(e){const t=this.workerNodes.length;if(0===t)return!0;const r=[],s=(e,s,i)=>{this.checkMessageWorkerId(e);const o=this.getWorkerNodeKeyByWorkerId(e.workerId);if(null!=e.taskFunctionOperationStatus&&o>=0&&o<t&&(r.push(e),r.length>=t))if(r.every(e=>!0===e.taskFunctionOperationStatus))s(!0);else{const t=r.find(e=>!1===e.taskFunctionOperationStatus);i(new Error(`Task function operation '${e.taskFunctionOperation}' failed on worker ${t?.workerId?.toString()} with error: '${t?.workerError?.error?.message??"Unknown error"}'`))}};let i;const o=[...this.workerNodes.keys()];try{return await new Promise((t,r)=>{i=e=>{s(e,t,r)};for(const t of o)this.registerWorkerMessageListener(t,i),this.sendToWorker(t,e)})}finally{if(null!=i)for(const e of o)this.deregisterWorkerMessageListener(e,i)}}setTasksQueuePriority(e){this.workerNodes[e].setTasksQueuePriority(this.getTasksQueuePriority())}setTasksQueueSize(e){for(const t of this.workerNodes)t.tasksQueueBackPressureSize=e}setTasksStealingOnBackPressure(){for(const e of this.workerNodes.keys())this.workerNodes[e].on("backPressure",this.handleWorkerNodeBackPressureEvent)}setTaskStealing(){for(const e of this.workerNodes.keys())this.workerNodes[e].on("idle",this.handleWorkerNodeIdleEvent)}shallExecuteTask(e){return 0===this.tasksQueueSize(e)&&this.workerNodes[e].usage.tasks.executing<this.opts.tasksQueueOptions.concurrency}shallUpdateTaskFunctionWorkerUsage(e){const t=this.getWorkerInfo(e);return null!=t&&Array.isArray(t.taskFunctionsProperties)&&t.taskFunctionsProperties.length>2}startMinimumNumberOfWorkers(e=!1){if(0!==this.minimumNumberOfWorkers){for(this.startingMinimumNumberOfWorkers=!0;this.workerNodes.reduce((e,t)=>t.info.dynamic?e:e+1,0)<this.minimumNumberOfWorkers;){const t=this.createAndSetupWorkerNode();e&&this.initWorkerNodeUsage(this.workerNodes[t])}this.startingMinimumNumberOfWorkers=!1}}stealTask=(e,t)=>{const r=this.workerNodes[t];if(null==r)return;if(!e.info.ready||e.info.stolen||e.info.stealing||e.info.queuedTaskAbortion||!r.info.ready||r.info.stolen||r.info.stealing||r.info.queuedTaskAbortion)return;r.info.stealing=!0,e.info.stolen=!0;const s=e.dequeueLastPrioritizedTask();return null==s?(e.info.stolen=!1,void(r.info.stealing=!1)):(e.info.stolen=!1,r.info.stealing=!1,this.handleTask(t,s),this.updateTaskStolenStatisticsWorkerUsage(t,s.name),s)};tasksQueueSize(e){const t=this.workerNodes[e];return null==t?0:t.tasksQueueSize()}unsetTasksStealingOnBackPressure(){for(const e of this.workerNodes.keys())this.workerNodes[e].off("backPressure",this.handleWorkerNodeBackPressureEvent)}unsetTaskStealing(){for(const e of this.workerNodes.keys())this.workerNodes[e].off("idle",this.handleWorkerNodeIdleEvent)}updateTaskSequentiallyStolenStatisticsWorkerUsage(e,t,r){const s=this.workerNodes[e];if(null!=s?.usage&&null!=t&&++s.usage.tasks.sequentiallyStolen,null!=t&&this.shallUpdateTaskFunctionWorkerUsage(e)&&null!=s.getTaskFunctionWorkerUsage(t)){const e=s.getTaskFunctionWorkerUsage(t);0===e.tasks.sequentiallyStolen||null!=r&&r===t&&e.tasks.sequentiallyStolen>0?++e.tasks.sequentiallyStolen:e.tasks.sequentiallyStolen>0&&(e.tasks.sequentiallyStolen=0)}}updateTaskStolenStatisticsWorkerUsage(e,t){const r=this.workerNodes[e];null!=r?.usage&&++r.usage.tasks.stolen,this.shallUpdateTaskFunctionWorkerUsage(e)&&null!=r.getTaskFunctionWorkerUsage(t)&&++r.getTaskFunctionWorkerUsage(t).tasks.stolen}workerNodeStealTask=e=>{const t=this.workerNodes[e];if(null==t)return;const r=this.workerNodes.slice().sort((e,t)=>t.usage.tasks.queued-e.usage.tasks.queued).find(e=>e!==t&&e.usage.tasks.queued>0);return null!=r?this.stealTask(r,e):void 0}}class Te extends Ne{get backPressure(){return this.internalBackPressure()}get busy(){return this.internalBusy()}get type(){return w.fixed}get worker(){return K.cluster}constructor(e,t,r={},s){super(e,t,r,s)}checkAndEmitDynamicWorkerCreationEvents(){}checkAndEmitDynamicWorkerDestructionEvents(){}deregisterWorkerMessageListener(e,t){this.workerNodes[e]?.worker.off("message",t)}isMain(){return e.isPrimary}registerOnceWorkerMessageListener(e,t){this.workerNodes[e]?.worker.once("message",t)}registerWorkerMessageListener(e,t){this.workerNodes[e]?.worker.on("message",t)}sendStartupMessageToWorker(e){this.sendToWorker(e,{ready:!1})}sendToWorker(e,t){this.workerNodes[e]?.worker.send({...t,workerId:this.getWorkerInfo(e)?.id})}setupHook(){e.setupPrimary({...this.opts.settings,exec:this.filePath})}shallCreateDynamicWorker(){return!1}}class We extends Te{get backPressure(){return this.full&&this.internalBackPressure()}get busy(){return this.full&&this.internalBusy()}get type(){return w.dynamic}emptyEventEmitted;fullEventEmitted;get empty(){return 0===this.minimumNumberOfWorkers&&this.workerNodes.length===this.minimumNumberOfWorkers}get full(){return this.workerNodes.length>=(this.maximumNumberOfWorkers??this.minimumNumberOfWorkers)}constructor(e,t,r,s={}){super(e,r,s,t),U(this.minimumNumberOfWorkers,this.maximumNumberOfWorkers),this.emptyEventEmitted=!1,this.fullEventEmitted=!1}checkAndEmitDynamicWorkerCreationEvents(){null!=this.emitter&&(!this.fullEventEmitted&&this.full&&(this.emitter.listenerCount(f.full)>0&&this.emitter.emit(f.full,this.info),this.fullEventEmitted=!0),this.emptyEventEmitted&&!this.empty&&(this.emptyEventEmitted=!1))}checkAndEmitDynamicWorkerDestructionEvents(){null!=this.emitter&&(this.fullEventEmitted&&!this.full&&(this.emitter.listenerCount(f.fullEnd)>0&&this.emitter.emit(f.fullEnd,this.info),this.fullEventEmitted=!1),!this.emptyEventEmitted&&this.empty&&(this.emitter.listenerCount(f.empty)>0&&this.emitter.emit(f.empty,this.info),this.emptyEventEmitted=!0))}shallCreateDynamicWorker(){return this.started&&!this.destroying&&(!this.full&&this.internalBusy()||this.empty)}}class Ee extends Ne{get backPressure(){return this.internalBackPressure()}get busy(){return this.internalBusy()}get type(){return w.fixed}get worker(){return K.thread}constructor(e,t,r={},s){super(e,t,r,s)}checkAndEmitDynamicWorkerCreationEvents(){}checkAndEmitDynamicWorkerDestructionEvents(){}deregisterWorkerMessageListener(e,t){this.workerNodes[e]?.messageChannel?.port1.off("message",t)}isMain(){return n}registerOnceWorkerMessageListener(e,t){this.workerNodes[e]?.messageChannel?.port1.once("message",t)}registerWorkerMessageListener(e,t){this.workerNodes[e]?.messageChannel?.port1.on("message",t)}sendStartupMessageToWorker(e){const t=this.workerNodes[e],r=t.messageChannel.port2;t.worker.postMessage({port:r,ready:!1,workerId:this.getWorkerInfo(e)?.id},[r])}sendToWorker(e,t,r){this.workerNodes[e]?.messageChannel?.port1.postMessage({...t,workerId:this.getWorkerInfo(e)?.id},r)}shallCreateDynamicWorker(){return!1}}class Se extends Ee{get backPressure(){return this.full&&this.internalBackPressure()}get busy(){return this.full&&this.internalBusy()}get type(){return w.dynamic}emptyEventEmitted;fullEventEmitted;get empty(){return 0===this.minimumNumberOfWorkers&&this.workerNodes.length===this.minimumNumberOfWorkers}get full(){return this.workerNodes.length>=(this.maximumNumberOfWorkers??this.minimumNumberOfWorkers)}constructor(e,t,r,s={}){super(e,r,s,t),U(this.minimumNumberOfWorkers,this.maximumNumberOfWorkers),this.emptyEventEmitted=!1,this.fullEventEmitted=!1}checkAndEmitDynamicWorkerCreationEvents(){null!=this.emitter&&(!this.fullEventEmitted&&this.full&&(this.emitter.listenerCount(f.full)>0&&this.emitter.emit(f.full,this.info),this.fullEventEmitted=!0),this.emptyEventEmitted&&!this.empty&&(this.emptyEventEmitted=!1))}checkAndEmitDynamicWorkerDestructionEvents(){null!=this.emitter&&(this.fullEventEmitted&&!this.full&&(this.emitter.listenerCount(f.fullEnd)>0&&this.emitter.emit(f.fullEnd,this.info),this.fullEventEmitted=!1),!this.emptyEventEmitted&&this.empty&&(this.emitter.listenerCount(f.empty)>0&&this.emitter.emit(f.empty,this.info),this.emptyEventEmitted=!0))}shallCreateDynamicWorker(){return this.started&&!this.destroying&&(!this.full&&this.internalBusy()||this.empty)}}class be extends Error{constructor(e){super(e),this.name="AbortError"}}const ve=(e,t)=>{if(xe(e),"function"!=typeof t.taskFunction)throw new TypeError(`taskFunction object 'taskFunction' property '${t.taskFunction}' is not a function`);D(t.priority),B(t.strategy),_(t.workerNodeKeys)},xe=e=>{if("string"!=typeof e)throw new TypeError("name parameter is not a string");if(0===e.trim().length)throw new TypeError("name parameter is an empty string")},Ie=6e4,Fe=Object.freeze({killBehavior:X.SOFT,killHandler:T,maxInactiveTime:Ie});class Oe{isMain;mainWorker;opts;activeInterval;lastTaskTimestamp;statistics;taskAbortFunctions;taskFunctions;constructor(e,t,r,s=Fe){if(this.isMain=e,this.mainWorker=t,this.opts=s,null==this.isMain)throw new Error("isMain parameter is mandatory");this.checkTaskFunctions(r),this.taskAbortFunctions=new Map,this.checkWorkerOptions(this.opts),this.isMain||this.getMainWorker().once("message",this.handleReadyMessage.bind(this))}addTaskFunction(e,t){try{if(xe(e),e===N)throw new Error("Cannot add a task function with the default reserved name");return"function"==typeof t&&(t={taskFunction:t}),ve(e,t),t.taskFunction=t.taskFunction.bind(this),this.taskFunctions.get(e)===this.taskFunctions.get(N)&&this.taskFunctions.set(N,t),this.taskFunctions.set(e,t),this.sendTaskFunctionsPropertiesToMainWorker(),{status:!0}}catch(e){return{error:e,status:!1}}}hasTaskFunction(e){try{xe(e)}catch(e){return{error:e,status:!1}}return{status:this.taskFunctions.has(e)}}listTaskFunctionsProperties(){let e=N;for(const[t,r]of this.taskFunctions)if(t!==N&&r===this.taskFunctions.get(N)){e=t;break}const t=[];for(const[r,s]of this.taskFunctions)r!==N&&r!==e&&t.push(P(r,s));return[P(N,this.taskFunctions.get(N)),P(e,this.taskFunctions.get(e)),...t]}removeTaskFunction(e){try{if(xe(e),e===N)throw new Error("Cannot remove the task function with the default reserved name");if(this.taskFunctions.get(e)===this.taskFunctions.get(N))throw new Error("Cannot remove the task function used as the default task function");const t=this.taskFunctions.delete(e);return this.sendTaskFunctionsPropertiesToMainWorker(),{status:t}}catch(e){return{error:e,status:!1}}}setDefaultTaskFunction(e){try{if(xe(e),e===N)throw new Error("Cannot set the default task function reserved name as the default task function");if(!this.taskFunctions.has(e))throw new Error("Cannot set the default task function to a non-existing task function");return this.taskFunctions.set(N,this.taskFunctions.get(e)),this.sendTaskFunctionsPropertiesToMainWorker(),{status:!0}}catch(e){return{error:e,status:!1}}}getMainWorker(){if(null==this.mainWorker)throw new Error("Main worker not set");return this.mainWorker}handleKillMessage(e){if(this.stopCheckActive(),I(this.opts.killHandler))this.opts.killHandler().then(()=>{this.sendToMainWorker({kill:"success"})}).catch(()=>{this.sendToMainWorker({kill:"failure"})});else try{this.opts.killHandler?.(),this.sendToMainWorker({kill:"success"})}catch{this.sendToMainWorker({kill:"failure"})}}handleTaskFunctionOperationMessage(e){const{taskFunction:t,taskFunctionOperation:r,taskFunctionProperties:s}=e;if(null==s)throw new Error("Cannot handle task function operation message without task function properties");let i;switch(r){case"add":if("string"!=typeof t)throw new Error(`Cannot handle task function operation ${r} message without task function`);i=this.addTaskFunction(s.name,{taskFunction:new Function(`return (${t})`)(),...null!=s.priority&&{priority:s.priority},...null!=s.strategy&&{strategy:s.strategy},...null!=s.workerNodeKeys&&{workerNodeKeys:s.workerNodeKeys}});break;case"default":i=this.setDefaultTaskFunction(s.name);break;case"remove":i=this.removeTaskFunction(s.name);break;default:i={error:new Error(`Unknown task function operation: ${r}`),status:!1}}const{error:o,status:n}=i;this.sendToMainWorker({taskFunctionOperation:r,taskFunctionOperationStatus:n,taskFunctionProperties:s,...!n&&null!=o&&{workerError:{name:s.name,...this.handleError(o)}}})}messageListener(e){this.checkMessageWorkerId(e);const{checkActive:t,data:r,kill:s,statistics:i,taskFunctionOperation:o,taskId:n,taskOperation:a}=e;null!=i?this.statistics=i:null!=t?t?this.startCheckActive():this.stopCheckActive():null!=o?this.handleTaskFunctionOperationMessage(e):null!=n&&null!=r?this.run(e):"abort"===a&&null!=n?this.taskAbortFunctions.has(n)&&this.taskAbortFunctions.get(n)?.():!0===s&&this.handleKillMessage(e)}run=e=>{const{abortable:t,data:r,name:s,taskId:i}=e,o=s??N;if(!this.taskFunctions.has(o))return void this.sendToMainWorker({taskId:i,workerError:{data:r,name:s,...this.handleError(new Error(`Task function '${o}' not found`))}});let n;n=!0===t?this.getAbortableTaskFunction(o,i):this.taskFunctions.get(o).taskFunction,I(n)?this.runAsync(n,e):this.runSync(n,e)};runAsync=(e,t)=>{const{abortable:r,data:s,name:i,taskId:o}=t;let n=this.beginTaskPerformance(i);e(s).then(e=>{n=this.endTaskPerformance(n),this.sendToMainWorker({data:e,taskId:o,taskPerformance:n})}).catch(e=>{this.sendToMainWorker({taskId:o,workerError:{data:s,name:i,...this.handleError(e)}})}).finally(()=>{this.updateLastTaskTimestamp(),!0===r&&this.taskAbortFunctions.delete(o)}).catch(T)};runSync=(e,t)=>{const{abortable:r,data:s,name:i,taskId:o}=t;try{let t=this.beginTaskPerformance(i);const r=e(s);t=this.endTaskPerformance(t),this.sendToMainWorker({data:r,taskId:o,taskPerformance:t})}catch(e){this.sendToMainWorker({taskId:o,workerError:{data:s,name:i,...this.handleError(e)}})}finally{this.updateLastTaskTimestamp(),!0===r&&this.taskAbortFunctions.delete(o)}};sendTaskFunctionsPropertiesToMainWorker(){this.sendToMainWorker({taskFunctionsProperties:this.listTaskFunctionsProperties()})}beginTaskPerformance(e){if(null==this.statistics)throw new Error("Performance statistics computation requirements not set");return{name:e??N,timestamp:y.now(),...this.statistics.elu&&{elu:y.eventLoopUtilization()}}}checkActive(){y.now()-this.lastTaskTimestamp>(this.opts.maxInactiveTime??Ie)&&this.sendToMainWorker({kill:this.opts.killBehavior})}checkMessageWorkerId(e){if(null==e.workerId)throw new Error(`Message worker id is not set: ${JSON.stringify(e)}`);if(e.workerId!==this.id)throw new Error(`Message worker id ${e.workerId.toString()} does not match the worker id ${this.id.toString()}: ${JSON.stringify(e)}`)}checkTaskFunctions(e){if(null==e)throw new Error("taskFunctions parameter is mandatory");if(this.taskFunctions=new Map,"function"==typeof e){const t={taskFunction:e.bind(this)};this.taskFunctions.set(N,t),this.taskFunctions.set("string"==typeof e.name&&e.name.trim().length>0?e.name:"fn1",t)}else{if(!v(e))throw new TypeError("taskFunctions parameter is not a function or a plain object");{let t=!0;for(let[r,s]of Object.entries(e))"function"==typeof s&&(s={taskFunction:s}),ve(r,s),s.taskFunction=s.taskFunction.bind(this),t&&(this.taskFunctions.set(N,s),t=!1),this.taskFunctions.set(r,s);if(t)throw new Error("taskFunctions parameter object is empty")}}}checkWorkerOptions(e){(e=>{if(null!=e&&!v(e))throw new TypeError("opts worker options parameter is not a plain object");if(null!=e?.killBehavior&&!Object.values(X).includes(e.killBehavior))throw new TypeError(`killBehavior option '${e.killBehavior}' is not valid`);if(null!=e?.maxInactiveTime&&(!Number.isSafeInteger(e.maxInactiveTime)||e.maxInactiveTime<5))throw new TypeError("maxInactiveTime option is not a positive integer greater or equal than 5");if(null!=e?.killHandler&&"function"!=typeof e.killHandler)throw new TypeError("killHandler option is not a function")})(e),this.opts={...Fe,...e}}endTaskPerformance(e){if(null==this.statistics)throw new Error("Performance statistics computation requirements not set");return{...e,...this.statistics.runTime&&{runTime:y.now()-e.timestamp},...this.statistics.elu&&{elu:y.eventLoopUtilization(e.elu)}}}getAbortableTaskFunction(e,t){return async r=>await new Promise((s,i)=>{this.taskAbortFunctions.set(t,()=>{i(new be(`Task '${e}' id '${t}' aborted`))});const o=this.taskFunctions.get(e).taskFunction;I(o)?o(r).then(s).catch(i):s(o(r))})}startCheckActive(){this.lastTaskTimestamp=y.now(),this.activeInterval=setInterval(this.checkActive.bind(this),(this.opts.maxInactiveTime??Ie)/2),this.activeInterval.unref()}stopCheckActive(){null!=this.activeInterval&&(clearInterval(this.activeInterval),this.activeInterval=void 0)}updateLastTaskTimestamp(){null!=this.activeInterval&&(this.lastTaskTimestamp=y.now())}}class Ce extends Oe{get id(){return this.getMainWorker().id}constructor(t,r={}){super(e.isPrimary,e.worker,t,r)}handleError(e){return{aborted:e instanceof be,message:e.message,stack:e.stack}}handleReadyMessage(e){if(e.workerId===this.id&&!1===e.ready)try{this.getMainWorker().on("message",this.messageListener.bind(this)),this.sendToMainWorker({ready:!0,taskFunctionsProperties:this.listTaskFunctionsProperties()})}catch{this.sendToMainWorker({ready:!1,taskFunctionsProperties:this.listTaskFunctionsProperties()})}}sendToMainWorker=e=>{this.getMainWorker().send({...e,workerId:this.id})}}class Pe extends Oe{get id(){return a}port;constructor(e,t={}){super(n,u,e,t)}handleError(e){return{aborted:e instanceof be,error:e,message:e.message,stack:e.stack}}handleKillMessage(e){super.handleKillMessage(e),this.port?.unref(),this.port?.close()}handleReadyMessage(e){if(e.workerId===this.id&&!1===e.ready&&null!=e.port)try{this.port=e.port,this.port.on("message",this.messageListener.bind(this)),this.sendToMainWorker({ready:!0,taskFunctionsProperties:this.listTaskFunctionsProperties()})}catch{this.sendToMainWorker({ready:!1,taskFunctionsProperties:this.listTaskFunctionsProperties()})}}sendToMainWorker=e=>{this.port?.postMessage({...e,workerId:this.id})}}export{Ce as ClusterWorker,We as DynamicClusterPool,Se as DynamicThreadPool,Te as FixedClusterPool,Ee as FixedThreadPool,X as KillBehaviors,z as Measurements,f as PoolEvents,w as PoolTypes,Pe as ThreadWorker,A as WorkerChoiceStrategies,K as WorkerTypes,W as availableParallelism};
2
2
  //# sourceMappingURL=index.mjs.map