poolifier 2.7.1 → 2.7.3
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/README.md +21 -24
- package/lib/index.d.ts +11 -12
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -0
- package/lib/index.mjs +2 -1
- package/lib/index.mjs.map +1 -0
- package/package.json +8 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/pools/pool.ts","../src/pools/worker.ts","../src/utils.ts","../src/pools/selection-strategies/selection-strategies-types.ts","../src/pools/utils.ts","../src/worker/worker-options.ts","../src/pools/selection-strategies/abstract-worker-choice-strategy.ts","../src/pools/selection-strategies/fair-share-worker-choice-strategy.ts","../src/pools/selection-strategies/interleaved-weighted-round-robin-worker-choice-strategy.ts","../src/pools/selection-strategies/least-busy-worker-choice-strategy.ts","../src/pools/selection-strategies/least-used-worker-choice-strategy.ts","../src/pools/selection-strategies/least-elu-worker-choice-strategy.ts","../src/pools/selection-strategies/round-robin-worker-choice-strategy.ts","../src/pools/selection-strategies/weighted-round-robin-worker-choice-strategy.ts","../src/pools/selection-strategies/worker-choice-strategy-context.ts","../src/circular-array.ts","../src/deque.ts","../src/pools/worker-node.ts","../src/pools/abstract-pool.ts","../src/pools/version.ts","../src/pools/cluster/fixed.ts","../src/pools/cluster/dynamic.ts","../src/pools/thread/fixed.ts","../src/pools/thread/dynamic.ts","../src/worker/utils.ts","../src/worker/abstract-worker.ts","../src/worker/cluster-worker.ts","../src/worker/thread-worker.ts"],"sourcesContent":["/**\n * Enumeration of pool types.\n */\nexport const PoolTypes = Object.freeze({\n /**\n * Fixed pool type.\n */\n fixed: 'fixed',\n /**\n * Dynamic pool type.\n */\n dynamic: 'dynamic'\n});\n/**\n * Enumeration of pool events.\n */\nexport const PoolEvents = Object.freeze({\n ready: 'ready',\n busy: 'busy',\n full: 'full',\n destroy: 'destroy',\n error: 'error',\n taskError: 'taskError',\n backPressure: 'backPressure'\n});\n//# sourceMappingURL=pool.js.map","/**\n * Enumeration of worker types.\n */\nexport const WorkerTypes = Object.freeze({\n thread: 'thread',\n cluster: 'cluster'\n});\n//# sourceMappingURL=worker.js.map","import * as os from 'node:os';\nimport { webcrypto } from 'node:crypto';\nimport { Worker as ClusterWorker } from 'node:cluster';\nimport { Worker as ThreadWorker } from 'node:worker_threads';\nimport { WorkerTypes } from './pools/worker';\n/**\n * Default task name.\n */\nexport const DEFAULT_TASK_NAME = 'default';\n/**\n * An intentional empty function.\n */\nexport const EMPTY_FUNCTION = Object.freeze(() => {\n /* Intentionally empty */\n});\n/**\n * Default worker choice strategy options.\n */\nexport const DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS = {\n retries: 6,\n runTime: { median: false },\n waitTime: { median: false },\n elu: { median: false }\n};\n/**\n * Default measurement statistics requirements.\n */\nexport const DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS = {\n aggregate: false,\n average: false,\n median: false\n};\n/**\n * Returns safe host OS optimized estimate of the default amount of parallelism a pool should use.\n * Always returns a value greater than zero.\n *\n * @returns The host OS optimized maximum pool size.\n */\nexport const availableParallelism = () => {\n let availableParallelism = 1;\n try {\n availableParallelism = os.availableParallelism();\n }\n catch {\n const cpus = os.cpus();\n if (Array.isArray(cpus) && cpus.length > 0) {\n availableParallelism = cpus.length;\n }\n }\n return availableParallelism;\n};\n/**\n * Returns the worker type of the given worker.\n *\n * @param worker - The worker to get the type of.\n * @returns The worker type of the given worker.\n * @internal\n */\nexport const getWorkerType = (worker) => {\n if (worker instanceof ThreadWorker) {\n return WorkerTypes.thread;\n }\n else if (worker instanceof ClusterWorker) {\n return WorkerTypes.cluster;\n }\n};\n/**\n * Returns the worker id of the given worker.\n *\n * @param worker - The worker to get the id of.\n * @returns The worker id of the given worker.\n * @internal\n */\nexport const getWorkerId = (worker) => {\n if (worker instanceof ThreadWorker) {\n return worker.threadId;\n }\n else if (worker instanceof ClusterWorker) {\n return worker.id;\n }\n};\n/**\n * Sleeps for the given amount of milliseconds.\n *\n * @param ms - The amount of milliseconds to sleep.\n * @returns A promise that resolves after the given amount of milliseconds.\n * @internal\n */\nexport const sleep = async (ms) => {\n await new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n};\n/**\n * Computes the retry delay in milliseconds using an exponential back off algorithm.\n *\n * @param retryNumber - The number of retries that have already been attempted\n * @param delayFactor - The base delay factor in milliseconds\n * @returns Delay in milliseconds\n * @internal\n */\nexport const exponentialDelay = (retryNumber = 0, delayFactor = 100) => {\n const delay = Math.pow(2, retryNumber) * delayFactor;\n const randomSum = delay * 0.2 * secureRandom(); // 0-20% of the delay\n return delay + randomSum;\n};\n/**\n * Computes the average of the given data set.\n *\n * @param dataSet - Data set.\n * @returns The average of the given data set.\n * @internal\n */\nexport const average = (dataSet) => {\n if (Array.isArray(dataSet) && dataSet.length === 0) {\n return 0;\n }\n if (Array.isArray(dataSet) && dataSet.length === 1) {\n return dataSet[0];\n }\n return (dataSet.reduce((accumulator, number) => accumulator + number, 0) /\n dataSet.length);\n};\n/**\n * Computes the median of the given data set.\n *\n * @param dataSet - Data set.\n * @returns The median of the given data set.\n * @internal\n */\nexport const median = (dataSet) => {\n if (Array.isArray(dataSet) && dataSet.length === 0) {\n return 0;\n }\n if (Array.isArray(dataSet) && dataSet.length === 1) {\n return dataSet[0];\n }\n const sortedDataSet = dataSet.slice().sort((a, b) => a - b);\n return ((sortedDataSet[(sortedDataSet.length - 1) >> 1] +\n sortedDataSet[sortedDataSet.length >> 1]) /\n 2);\n};\n/**\n * Rounds the given number to the given scale.\n * The rounding is done using the \"round half away from zero\" method.\n *\n * @param num - The number to round.\n * @param scale - The scale to round to.\n * @returns The rounded number.\n * @internal\n */\nexport const round = (num, scale = 2) => {\n const rounder = Math.pow(10, scale);\n return Math.round(num * rounder * (1 + Number.EPSILON)) / rounder;\n};\n/**\n * Is the given object a plain object?\n *\n * @param obj - The object to check.\n * @returns `true` if the given object is a plain object, `false` otherwise.\n * @internal\n */\nexport const isPlainObject = (obj) => typeof obj === 'object' &&\n obj !== null &&\n obj?.constructor === Object &&\n Object.prototype.toString.call(obj) === '[object Object]';\n/**\n * Detects whether the given value is a kill behavior or not.\n *\n * @typeParam KB - Which specific KillBehavior type to test against.\n * @param killBehavior - Which kind of kill behavior to detect.\n * @param value - Any value.\n * @returns `true` if `value` was strictly equals to `killBehavior`, otherwise `false`.\n * @internal\n */\nexport const isKillBehavior = (killBehavior, value) => {\n return value === killBehavior;\n};\n/**\n * Detects whether the given value is an asynchronous function or not.\n *\n * @param fn - Any value.\n * @returns `true` if `fn` was an asynchronous function, otherwise `false`.\n * @internal\n */\nexport const isAsyncFunction = (fn) => {\n return typeof fn === 'function' && fn.constructor.name === 'AsyncFunction';\n};\n/**\n * Generates a cryptographically secure random number in the [0,1[ range\n *\n * @returns A number in the [0,1[ range\n * @internal\n */\nexport const secureRandom = () => {\n return webcrypto.getRandomValues(new Uint32Array(1))[0] / 0x100000000;\n};\n/**\n * Returns the minimum of the given numbers.\n * If no numbers are given, `Infinity` is returned.\n *\n * @param args - The numbers to get the minimum of.\n * @returns The minimum of the given numbers.\n * @internal\n */\nexport const min = (...args) => args.reduce((minimum, num) => (minimum < num ? minimum : num), Infinity);\n/**\n * Returns the maximum of the given numbers.\n * If no numbers are given, `-Infinity` is returned.\n *\n * @param args - The numbers to get the maximum of.\n * @returns The maximum of the given numbers.\n * @internal\n */\nexport const max = (...args) => args.reduce((maximum, num) => (maximum > num ? maximum : num), -Infinity);\n//# sourceMappingURL=utils.js.map","/**\n * Enumeration of worker choice strategies.\n */\nexport const WorkerChoiceStrategies = Object.freeze({\n /**\n * Round robin worker selection strategy.\n */\n ROUND_ROBIN: 'ROUND_ROBIN',\n /**\n * Least used worker selection strategy.\n */\n LEAST_USED: 'LEAST_USED',\n /**\n * Least busy worker selection strategy.\n */\n LEAST_BUSY: 'LEAST_BUSY',\n /**\n * Least ELU worker selection strategy.\n */\n LEAST_ELU: 'LEAST_ELU',\n /**\n * Fair share worker selection strategy.\n */\n FAIR_SHARE: 'FAIR_SHARE',\n /**\n * Weighted round robin worker selection strategy.\n */\n WEIGHTED_ROUND_ROBIN: 'WEIGHTED_ROUND_ROBIN',\n /**\n * Interleaved weighted round robin worker selection strategy.\n *\n * @experimental\n */\n INTERLEAVED_WEIGHTED_ROUND_ROBIN: 'INTERLEAVED_WEIGHTED_ROUND_ROBIN'\n});\n/**\n * Enumeration of measurements.\n */\nexport const Measurements = Object.freeze({\n runTime: 'runTime',\n waitTime: 'waitTime',\n elu: 'elu'\n});\n//# sourceMappingURL=selection-strategies-types.js.map","import { existsSync } from 'node:fs';\nimport { average, isPlainObject, max, median, min } from '../utils';\nimport { WorkerChoiceStrategies } from './selection-strategies/selection-strategies-types';\nexport const checkFilePath = (filePath) => {\n if (filePath == null ||\n typeof filePath !== 'string' ||\n (typeof filePath === 'string' && filePath.trim().length === 0)) {\n throw new Error('Please specify a file with a worker implementation');\n }\n if (!existsSync(filePath)) {\n throw new Error(`Cannot find the worker file '${filePath}'`);\n }\n};\nexport const checkDynamicPoolSize = (min, max) => {\n if (max == null) {\n throw new TypeError('Cannot instantiate a dynamic pool without specifying the maximum pool size');\n }\n else if (!Number.isSafeInteger(max)) {\n throw new TypeError('Cannot instantiate a dynamic pool with a non safe integer maximum pool size');\n }\n else if (min > max) {\n throw new RangeError('Cannot instantiate a dynamic pool with a maximum pool size inferior to the minimum pool size');\n }\n else if (max === 0) {\n throw new RangeError('Cannot instantiate a dynamic pool with a maximum pool size equal to zero');\n }\n else if (min === max) {\n throw new RangeError('Cannot instantiate a dynamic pool with a minimum pool size equal to the maximum pool size. Use a fixed pool instead');\n }\n};\nexport const checkValidWorkerChoiceStrategy = (workerChoiceStrategy) => {\n if (workerChoiceStrategy != null &&\n !Object.values(WorkerChoiceStrategies).includes(workerChoiceStrategy)) {\n throw new Error(`Invalid worker choice strategy '${workerChoiceStrategy}'`);\n }\n};\nexport const checkValidTasksQueueOptions = (tasksQueueOptions) => {\n if (tasksQueueOptions != null && !isPlainObject(tasksQueueOptions)) {\n throw new TypeError('Invalid tasks queue options: must be a plain object');\n }\n if (tasksQueueOptions?.concurrency != null &&\n !Number.isSafeInteger(tasksQueueOptions.concurrency)) {\n throw new TypeError('Invalid worker node tasks concurrency: must be an integer');\n }\n if (tasksQueueOptions?.concurrency != null &&\n tasksQueueOptions.concurrency <= 0) {\n throw new RangeError(`Invalid worker node tasks concurrency: ${tasksQueueOptions.concurrency} is a negative integer or zero`);\n }\n if (tasksQueueOptions?.size != null &&\n !Number.isSafeInteger(tasksQueueOptions.size)) {\n throw new TypeError('Invalid worker node tasks queue size: must be an integer');\n }\n if (tasksQueueOptions?.size != null && tasksQueueOptions.size <= 0) {\n throw new RangeError(`Invalid worker node tasks queue size: ${tasksQueueOptions.size} is a negative integer or zero`);\n }\n};\nexport const checkWorkerNodeArguments = (worker, tasksQueueBackPressureSize) => {\n if (worker == null) {\n throw new TypeError('Cannot construct a worker node without a worker');\n }\n if (tasksQueueBackPressureSize == null) {\n throw new TypeError('Cannot construct a worker node without a tasks queue back pressure size');\n }\n if (!Number.isSafeInteger(tasksQueueBackPressureSize)) {\n throw new TypeError('Cannot construct a worker node with a tasks queue back pressure size that is not an integer');\n }\n if (tasksQueueBackPressureSize <= 0) {\n throw new RangeError('Cannot construct a worker node with a tasks queue back pressure size that is not a positive integer');\n }\n};\n/**\n * Updates the given measurement statistics.\n *\n * @param measurementStatistics - The measurement statistics to update.\n * @param measurementRequirements - The measurement statistics requirements.\n * @param measurementValue - The measurement value.\n * @param numberOfMeasurements - The number of measurements.\n * @internal\n */\nexport const updateMeasurementStatistics = (measurementStatistics, measurementRequirements, measurementValue) => {\n if (measurementRequirements.aggregate) {\n measurementStatistics.aggregate =\n (measurementStatistics.aggregate ?? 0) + measurementValue;\n measurementStatistics.minimum = min(measurementValue, measurementStatistics.minimum ?? Infinity);\n measurementStatistics.maximum = max(measurementValue, measurementStatistics.maximum ?? -Infinity);\n if ((measurementRequirements.average || measurementRequirements.median) &&\n measurementValue != null) {\n measurementStatistics.history.push(measurementValue);\n if (measurementRequirements.average) {\n measurementStatistics.average = average(measurementStatistics.history);\n }\n else if (measurementStatistics.average != null) {\n delete measurementStatistics.average;\n }\n if (measurementRequirements.median) {\n measurementStatistics.median = median(measurementStatistics.history);\n }\n else if (measurementStatistics.median != null) {\n delete measurementStatistics.median;\n }\n }\n }\n};\n//# sourceMappingURL=utils.js.map","/**\n * Enumeration of kill behaviors.\n */\nexport const KillBehaviors = Object.freeze({\n /**\n * If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still executing or queued, then the worker **wont** be deleted.\n */\n SOFT: 'SOFT',\n /**\n * If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still executing or queued, then the worker will be deleted.\n */\n HARD: 'HARD'\n});\n//# sourceMappingURL=worker-options.js.map","import { cpus } from 'node:os';\nimport { DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS, DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS } from '../../utils';\n/**\n * Worker choice strategy abstract base class.\n *\n * @typeParam Worker - Type of worker which manages the strategy.\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n * @typeParam Response - Type of execution response. This can only be structured-cloneable data.\n */\nexport class AbstractWorkerChoiceStrategy {\n pool;\n opts;\n /**\n * The next worker node key.\n */\n nextWorkerNodeKey = 0;\n /**\n * The previous worker node key.\n */\n previousWorkerNodeKey = 0;\n /** @inheritDoc */\n strategyPolicy = {\n dynamicWorkerUsage: false,\n dynamicWorkerReady: true\n };\n /** @inheritDoc */\n taskStatisticsRequirements = {\n runTime: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS,\n waitTime: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS,\n elu: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS\n };\n /**\n * Constructs a worker choice strategy bound to the pool.\n *\n * @param pool - The pool instance.\n * @param opts - The worker choice strategy options.\n */\n constructor(pool, opts = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS) {\n this.pool = pool;\n this.opts = opts;\n this.opts = { ...DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS, ...opts };\n this.choose = this.choose.bind(this);\n }\n setTaskStatisticsRequirements(opts) {\n this.toggleMedianMeasurementStatisticsRequirements(this.taskStatisticsRequirements.runTime, opts.runTime?.median);\n this.toggleMedianMeasurementStatisticsRequirements(this.taskStatisticsRequirements.waitTime, opts.waitTime?.median);\n this.toggleMedianMeasurementStatisticsRequirements(this.taskStatisticsRequirements.elu, opts.elu?.median);\n }\n toggleMedianMeasurementStatisticsRequirements(measurementStatisticsRequirements, toggleMedian) {\n if (measurementStatisticsRequirements.average && toggleMedian) {\n measurementStatisticsRequirements.average = false;\n measurementStatisticsRequirements.median = toggleMedian;\n }\n if (measurementStatisticsRequirements.median && !toggleMedian) {\n measurementStatisticsRequirements.average = true;\n measurementStatisticsRequirements.median = toggleMedian;\n }\n }\n resetWorkerNodeKeyProperties() {\n this.nextWorkerNodeKey = 0;\n this.previousWorkerNodeKey = 0;\n }\n /** @inheritDoc */\n setOptions(opts) {\n this.opts = { ...DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS, ...opts };\n this.setTaskStatisticsRequirements(this.opts);\n }\n /**\n * Whether the worker node is ready or not.\n *\n * @param workerNodeKey - The worker node key.\n * @returns Whether the worker node is ready or not.\n */\n isWorkerNodeReady(workerNodeKey) {\n return this.pool.workerNodes[workerNodeKey].info.ready;\n }\n /**\n * Whether the worker node has back pressure or not (i.e. its tasks queue is full).\n *\n * @param workerNodeKey - The worker node key.\n * @returns `true` if the worker node has back pressure, `false` otherwise.\n */\n hasWorkerNodeBackPressure(workerNodeKey) {\n return this.pool.hasWorkerNodeBackPressure(workerNodeKey);\n }\n /**\n * Whether the worker node is eligible or not.\n * A worker node is eligible if it is ready and does not have back pressure.\n *\n * @param workerNodeKey - The worker node key.\n * @returns `true` if the worker node is eligible, `false` otherwise.\n * @see {@link isWorkerNodeReady}\n * @see {@link hasWorkerNodeBackPressure}\n */\n isWorkerNodeEligible(workerNodeKey) {\n return (this.isWorkerNodeReady(workerNodeKey) &&\n !this.hasWorkerNodeBackPressure(workerNodeKey));\n }\n /**\n * Gets the worker node task runtime.\n * If the task statistics require the average runtime, the average runtime is returned.\n * If the task statistics require the median runtime , the median runtime is returned.\n *\n * @param workerNodeKey - The worker node key.\n * @returns The worker node task runtime.\n */\n getWorkerNodeTaskRunTime(workerNodeKey) {\n return this.taskStatisticsRequirements.runTime.median\n ? this.pool.workerNodes[workerNodeKey].usage.runTime.median ?? 0\n : this.pool.workerNodes[workerNodeKey].usage.runTime.average ?? 0;\n }\n /**\n * Gets the worker node task wait time.\n * If the task statistics require the average wait time, the average wait time is returned.\n * If the task statistics require the median wait time, the median wait time is returned.\n *\n * @param workerNodeKey - The worker node key.\n * @returns The worker node task wait time.\n */\n getWorkerNodeTaskWaitTime(workerNodeKey) {\n return this.taskStatisticsRequirements.waitTime.median\n ? this.pool.workerNodes[workerNodeKey].usage.waitTime.median ?? 0\n : this.pool.workerNodes[workerNodeKey].usage.waitTime.average ?? 0;\n }\n /**\n * Gets the worker node task ELU.\n * If the task statistics require the average ELU, the average ELU is returned.\n * If the task statistics require the median ELU, the median ELU is returned.\n *\n * @param workerNodeKey - The worker node key.\n * @returns The worker node task ELU.\n */\n getWorkerNodeTaskElu(workerNodeKey) {\n return this.taskStatisticsRequirements.elu.median\n ? this.pool.workerNodes[workerNodeKey].usage.elu.active.median ?? 0\n : this.pool.workerNodes[workerNodeKey].usage.elu.active.average ?? 0;\n }\n /**\n * Sets safely the previous worker node key.\n *\n * @param workerNodeKey - The worker node key.\n */\n setPreviousWorkerNodeKey(workerNodeKey) {\n this.previousWorkerNodeKey = workerNodeKey ?? this.previousWorkerNodeKey;\n }\n /**\n * Check the next worker node eligibility.\n */\n checkNextWorkerNodeEligibility() {\n if (!this.isWorkerNodeEligible(this.nextWorkerNodeKey)) {\n this.nextWorkerNodeKey = undefined;\n }\n }\n computeDefaultWorkerWeight() {\n let cpusCycleTimeWeight = 0;\n for (const cpu of cpus()) {\n // CPU estimated cycle time\n const numberOfDigits = cpu.speed.toString().length - 1;\n const cpuCycleTime = 1 / (cpu.speed / Math.pow(10, numberOfDigits));\n cpusCycleTimeWeight += cpuCycleTime * Math.pow(10, numberOfDigits);\n }\n return Math.round(cpusCycleTimeWeight / cpus().length);\n }\n}\n//# sourceMappingURL=abstract-worker-choice-strategy.js.map","import { DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS, DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS } from '../../utils';\nimport { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy';\nimport { Measurements } from './selection-strategies-types';\n/**\n * Selects the next worker with a fair share scheduling algorithm.\n * Loosely modeled after the fair queueing algorithm: https://en.wikipedia.org/wiki/Fair_queuing.\n *\n * @typeParam Worker - Type of worker which manages the strategy.\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n * @typeParam Response - Type of execution response. This can only be structured-cloneable data.\n */\nexport class FairShareWorkerChoiceStrategy extends AbstractWorkerChoiceStrategy {\n /** @inheritDoc */\n taskStatisticsRequirements = {\n runTime: {\n aggregate: true,\n average: true,\n median: false\n },\n waitTime: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS,\n elu: {\n aggregate: true,\n average: true,\n median: false\n }\n };\n /** @inheritDoc */\n constructor(pool, opts = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS) {\n super(pool, opts);\n this.setTaskStatisticsRequirements(this.opts);\n }\n /** @inheritDoc */\n reset() {\n for (const workerNode of this.pool.workerNodes) {\n delete workerNode.strategyData?.virtualTaskEndTimestamp;\n }\n return true;\n }\n /** @inheritDoc */\n update(workerNodeKey) {\n this.pool.workerNodes[workerNodeKey].strategyData = {\n virtualTaskEndTimestamp: this.computeWorkerNodeVirtualTaskEndTimestamp(workerNodeKey)\n };\n return true;\n }\n /** @inheritDoc */\n choose() {\n this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey);\n this.nextWorkerNodeKey = this.fairShareNextWorkerNodeKey();\n return this.nextWorkerNodeKey;\n }\n /** @inheritDoc */\n remove() {\n return true;\n }\n fairShareNextWorkerNodeKey() {\n return this.pool.workerNodes.reduce((minWorkerNodeKey, workerNode, workerNodeKey, workerNodes) => {\n if (workerNode.strategyData?.virtualTaskEndTimestamp == null) {\n workerNode.strategyData = {\n virtualTaskEndTimestamp: this.computeWorkerNodeVirtualTaskEndTimestamp(workerNodeKey)\n };\n }\n return workerNode.strategyData.virtualTaskEndTimestamp <\n workerNodes[minWorkerNodeKey].strategyData\n .virtualTaskEndTimestamp\n ? workerNodeKey\n : minWorkerNodeKey;\n }, 0);\n }\n /**\n * Computes the worker node key virtual task end timestamp.\n *\n * @param workerNodeKey - The worker node key.\n * @returns The worker node key virtual task end timestamp.\n */\n computeWorkerNodeVirtualTaskEndTimestamp(workerNodeKey) {\n return this.getWorkerNodeVirtualTaskEndTimestamp(workerNodeKey, this.getWorkerNodeVirtualTaskStartTimestamp(workerNodeKey));\n }\n getWorkerNodeVirtualTaskEndTimestamp(workerNodeKey, workerNodeVirtualTaskStartTimestamp) {\n const workerNodeTaskRunTime = this.opts.measurement === Measurements.elu\n ? this.getWorkerNodeTaskElu(workerNodeKey)\n : this.getWorkerNodeTaskRunTime(workerNodeKey);\n return workerNodeVirtualTaskStartTimestamp + workerNodeTaskRunTime;\n }\n getWorkerNodeVirtualTaskStartTimestamp(workerNodeKey) {\n const virtualTaskEndTimestamp = this.pool.workerNodes[workerNodeKey]?.strategyData\n ?.virtualTaskEndTimestamp;\n const now = performance.now();\n return now < (virtualTaskEndTimestamp ?? -Infinity)\n ? virtualTaskEndTimestamp\n : now;\n }\n}\n//# sourceMappingURL=fair-share-worker-choice-strategy.js.map","import { DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS, DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS } from '../../utils';\nimport { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy';\n/**\n * Selects the next worker with an interleaved weighted round robin scheduling algorithm.\n *\n * @typeParam Worker - Type of worker which manages the strategy.\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n * @typeParam Response - Type of execution response. This can only be structured-cloneable data.\n */\nexport class InterleavedWeightedRoundRobinWorkerChoiceStrategy extends AbstractWorkerChoiceStrategy {\n /** @inheritDoc */\n taskStatisticsRequirements = {\n runTime: {\n aggregate: true,\n average: true,\n median: false\n },\n waitTime: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS,\n elu: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS\n };\n /**\n * Round id.\n */\n roundId = 0;\n /**\n * Default worker weight.\n */\n defaultWorkerWeight;\n /**\n * Round weights.\n */\n roundWeights;\n /**\n * Worker node id.\n */\n workerNodeId = 0;\n /**\n * Worker node virtual task runtime.\n */\n workerNodeVirtualTaskRunTime = 0;\n /** @inheritDoc */\n constructor(pool, opts = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS) {\n super(pool, opts);\n this.setTaskStatisticsRequirements(this.opts);\n this.defaultWorkerWeight = this.computeDefaultWorkerWeight();\n this.roundWeights = this.getRoundWeights();\n }\n /** @inheritDoc */\n reset() {\n this.resetWorkerNodeKeyProperties();\n this.roundId = 0;\n this.workerNodeId = 0;\n this.workerNodeVirtualTaskRunTime = 0;\n return true;\n }\n /** @inheritDoc */\n update() {\n return true;\n }\n /** @inheritDoc */\n choose() {\n for (let roundIndex = this.roundId; roundIndex < this.roundWeights.length; roundIndex++) {\n this.roundId = roundIndex;\n for (let workerNodeKey = this.workerNodeId; workerNodeKey < this.pool.workerNodes.length; workerNodeKey++) {\n this.workerNodeId = workerNodeKey;\n if (this.workerNodeId !== this.nextWorkerNodeKey &&\n this.workerNodeVirtualTaskRunTime !== 0) {\n this.workerNodeVirtualTaskRunTime = 0;\n }\n const workerWeight = this.opts.weights?.[workerNodeKey] ?? this.defaultWorkerWeight;\n if (workerWeight >= this.roundWeights[roundIndex] &&\n this.workerNodeVirtualTaskRunTime < workerWeight) {\n this.workerNodeVirtualTaskRunTime =\n this.workerNodeVirtualTaskRunTime +\n this.getWorkerNodeTaskRunTime(workerNodeKey);\n this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey);\n this.nextWorkerNodeKey = workerNodeKey;\n return this.nextWorkerNodeKey;\n }\n }\n }\n this.interleavedWeightedRoundRobinNextWorkerNodeId();\n }\n interleavedWeightedRoundRobinNextWorkerNodeId() {\n if (this.roundId === this.roundWeights.length - 1 &&\n this.workerNodeId === this.pool.workerNodes.length - 1) {\n this.roundId = 0;\n this.workerNodeId = 0;\n }\n else if (this.workerNodeId === this.pool.workerNodes.length - 1) {\n this.roundId = this.roundId + 1;\n this.workerNodeId = 0;\n }\n else {\n this.workerNodeId = this.workerNodeId + 1;\n }\n }\n /** @inheritDoc */\n remove(workerNodeKey) {\n if (this.pool.workerNodes.length === 0) {\n this.reset();\n }\n if (this.workerNodeId === workerNodeKey &&\n this.workerNodeId > this.pool.workerNodes.length - 1) {\n this.workerNodeId = this.pool.workerNodes.length - 1;\n }\n if (this.previousWorkerNodeKey === workerNodeKey &&\n this.previousWorkerNodeKey > this.pool.workerNodes.length - 1) {\n this.previousWorkerNodeKey = this.pool.workerNodes.length - 1;\n }\n return true;\n }\n /** @inheritDoc */\n setOptions(opts) {\n super.setOptions(opts);\n this.roundWeights = this.getRoundWeights();\n }\n getRoundWeights() {\n if (this.opts.weights == null) {\n return [this.defaultWorkerWeight];\n }\n return [\n ...new Set(Object.values(this.opts.weights)\n .slice()\n .sort((a, b) => a - b))\n ];\n }\n}\n//# sourceMappingURL=interleaved-weighted-round-robin-worker-choice-strategy.js.map","import { DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS, DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS } from '../../utils';\nimport { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy';\n/**\n * Selects the least busy worker.\n *\n * @typeParam Worker - Type of worker which manages the strategy.\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n * @typeParam Response - Type of execution response. This can only be structured-cloneable data.\n */\nexport class LeastBusyWorkerChoiceStrategy extends AbstractWorkerChoiceStrategy {\n /** @inheritDoc */\n taskStatisticsRequirements = {\n runTime: {\n aggregate: true,\n average: false,\n median: false\n },\n waitTime: {\n aggregate: true,\n average: false,\n median: false\n },\n elu: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS\n };\n /** @inheritDoc */\n constructor(pool, opts = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS) {\n super(pool, opts);\n this.setTaskStatisticsRequirements(this.opts);\n }\n /** @inheritDoc */\n reset() {\n return true;\n }\n /** @inheritDoc */\n update() {\n return true;\n }\n /** @inheritDoc */\n choose() {\n this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey);\n this.nextWorkerNodeKey = this.leastBusyNextWorkerNodeKey();\n return this.nextWorkerNodeKey;\n }\n /** @inheritDoc */\n remove() {\n return true;\n }\n leastBusyNextWorkerNodeKey() {\n return this.pool.workerNodes.reduce((minWorkerNodeKey, workerNode, workerNodeKey, workerNodes) => {\n return (workerNode.usage.runTime.aggregate ?? 0) +\n (workerNode.usage.waitTime.aggregate ?? 0) <\n (workerNodes[minWorkerNodeKey].usage.runTime.aggregate ?? 0) +\n (workerNodes[minWorkerNodeKey].usage.waitTime.aggregate ?? 0)\n ? workerNodeKey\n : minWorkerNodeKey;\n }, 0);\n }\n}\n//# sourceMappingURL=least-busy-worker-choice-strategy.js.map","import { DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS } from '../../utils';\nimport { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy';\n/**\n * Selects the least used worker.\n *\n * @typeParam Worker - Type of worker which manages the strategy.\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n * @typeParam Response - Type of execution response. This can only be structured-cloneable data.\n */\nexport class LeastUsedWorkerChoiceStrategy extends AbstractWorkerChoiceStrategy {\n /** @inheritDoc */\n constructor(pool, opts = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS) {\n super(pool, opts);\n this.setTaskStatisticsRequirements(this.opts);\n }\n /** @inheritDoc */\n reset() {\n return true;\n }\n /** @inheritDoc */\n update() {\n return true;\n }\n /** @inheritDoc */\n choose() {\n this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey);\n this.nextWorkerNodeKey = this.leastUsedNextWorkerNodeKey();\n return this.nextWorkerNodeKey;\n }\n /** @inheritDoc */\n remove() {\n return true;\n }\n leastUsedNextWorkerNodeKey() {\n return this.pool.workerNodes.reduce((minWorkerNodeKey, workerNode, workerNodeKey, workerNodes) => {\n return workerNode.usage.tasks.executed +\n workerNode.usage.tasks.executing +\n workerNode.usage.tasks.queued <\n workerNodes[minWorkerNodeKey].usage.tasks.executed +\n workerNodes[minWorkerNodeKey].usage.tasks.executing +\n workerNodes[minWorkerNodeKey].usage.tasks.queued\n ? workerNodeKey\n : minWorkerNodeKey;\n }, 0);\n }\n}\n//# sourceMappingURL=least-used-worker-choice-strategy.js.map","import { DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS, DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS } from '../../utils';\nimport { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy';\n/**\n * Selects the worker with the least ELU.\n *\n * @typeParam Worker - Type of worker which manages the strategy.\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n * @typeParam Response - Type of execution response. This can only be structured-cloneable data.\n */\nexport class LeastEluWorkerChoiceStrategy extends AbstractWorkerChoiceStrategy {\n /** @inheritDoc */\n taskStatisticsRequirements = {\n runTime: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS,\n waitTime: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS,\n elu: {\n aggregate: true,\n average: false,\n median: false\n }\n };\n /** @inheritDoc */\n constructor(pool, opts = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS) {\n super(pool, opts);\n this.setTaskStatisticsRequirements(this.opts);\n }\n /** @inheritDoc */\n reset() {\n return true;\n }\n /** @inheritDoc */\n update() {\n return true;\n }\n /** @inheritDoc */\n choose() {\n this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey);\n this.nextWorkerNodeKey = this.leastEluNextWorkerNodeKey();\n return this.nextWorkerNodeKey;\n }\n /** @inheritDoc */\n remove() {\n return true;\n }\n leastEluNextWorkerNodeKey() {\n return this.pool.workerNodes.reduce((minWorkerNodeKey, workerNode, workerNodeKey, workerNodes) => {\n return (workerNode.usage.elu.active.aggregate ?? 0) <\n (workerNodes[minWorkerNodeKey].usage.elu.active.aggregate ?? 0)\n ? workerNodeKey\n : minWorkerNodeKey;\n }, 0);\n }\n}\n//# sourceMappingURL=least-elu-worker-choice-strategy.js.map","import { DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS } from '../../utils';\nimport { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy';\n/**\n * Selects the next worker in a round robin fashion.\n *\n * @typeParam Worker - Type of worker which manages the strategy.\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n * @typeParam Response - Type of execution response. This can only be structured-cloneable data.\n */\nexport class RoundRobinWorkerChoiceStrategy extends AbstractWorkerChoiceStrategy {\n /** @inheritDoc */\n constructor(pool, opts = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS) {\n super(pool, opts);\n this.setTaskStatisticsRequirements(this.opts);\n }\n /** @inheritDoc */\n reset() {\n this.resetWorkerNodeKeyProperties();\n return true;\n }\n /** @inheritDoc */\n update() {\n return true;\n }\n /** @inheritDoc */\n choose() {\n const chosenWorkerNodeKey = this.nextWorkerNodeKey;\n this.setPreviousWorkerNodeKey(chosenWorkerNodeKey);\n this.roundRobinNextWorkerNodeKey();\n return chosenWorkerNodeKey;\n }\n /** @inheritDoc */\n remove(workerNodeKey) {\n if (this.pool.workerNodes.length === 0) {\n this.reset();\n }\n if (this.nextWorkerNodeKey === workerNodeKey &&\n this.nextWorkerNodeKey > this.pool.workerNodes.length - 1) {\n this.nextWorkerNodeKey = this.pool.workerNodes.length - 1;\n }\n if (this.previousWorkerNodeKey === workerNodeKey &&\n this.previousWorkerNodeKey > this.pool.workerNodes.length - 1) {\n this.previousWorkerNodeKey = this.pool.workerNodes.length - 1;\n }\n return true;\n }\n roundRobinNextWorkerNodeKey() {\n this.nextWorkerNodeKey =\n this.nextWorkerNodeKey === this.pool.workerNodes.length - 1\n ? 0\n : (this.nextWorkerNodeKey ?? this.previousWorkerNodeKey) + 1;\n return this.nextWorkerNodeKey;\n }\n}\n//# sourceMappingURL=round-robin-worker-choice-strategy.js.map","import { DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS, DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS } from '../../utils';\nimport { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy';\n/**\n * Selects the next worker with a weighted round robin scheduling algorithm.\n * Loosely modeled after the weighted round robin queueing algorithm: https://en.wikipedia.org/wiki/Weighted_round_robin.\n *\n * @typeParam Worker - Type of worker which manages the strategy.\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n * @typeParam Response - Type of execution response. This can only be structured-cloneable data.\n */\nexport class WeightedRoundRobinWorkerChoiceStrategy extends AbstractWorkerChoiceStrategy {\n /** @inheritDoc */\n taskStatisticsRequirements = {\n runTime: {\n aggregate: true,\n average: true,\n median: false\n },\n waitTime: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS,\n elu: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS\n };\n /**\n * Default worker weight.\n */\n defaultWorkerWeight;\n /**\n * Worker node virtual task runtime.\n */\n workerNodeVirtualTaskRunTime = 0;\n /** @inheritDoc */\n constructor(pool, opts = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS) {\n super(pool, opts);\n this.setTaskStatisticsRequirements(this.opts);\n this.defaultWorkerWeight = this.computeDefaultWorkerWeight();\n }\n /** @inheritDoc */\n reset() {\n this.resetWorkerNodeKeyProperties();\n this.workerNodeVirtualTaskRunTime = 0;\n return true;\n }\n /** @inheritDoc */\n update() {\n return true;\n }\n /** @inheritDoc */\n choose() {\n this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey);\n return this.weightedRoundRobinNextWorkerNodeKey();\n }\n /** @inheritDoc */\n remove(workerNodeKey) {\n if (this.pool.workerNodes.length === 0) {\n this.reset();\n }\n if (this.nextWorkerNodeKey === workerNodeKey) {\n this.workerNodeVirtualTaskRunTime = 0;\n if (this.nextWorkerNodeKey > this.pool.workerNodes.length - 1) {\n this.nextWorkerNodeKey = this.pool.workerNodes.length - 1;\n }\n }\n if (this.previousWorkerNodeKey === workerNodeKey &&\n this.previousWorkerNodeKey > this.pool.workerNodes.length - 1) {\n this.previousWorkerNodeKey = this.pool.workerNodes.length - 1;\n }\n return true;\n }\n weightedRoundRobinNextWorkerNodeKey() {\n const workerWeight = this.opts.weights?.[this.nextWorkerNodeKey ?? this.previousWorkerNodeKey] ?? this.defaultWorkerWeight;\n if (this.workerNodeVirtualTaskRunTime < workerWeight) {\n this.workerNodeVirtualTaskRunTime =\n this.workerNodeVirtualTaskRunTime +\n this.getWorkerNodeTaskRunTime(this.nextWorkerNodeKey ?? this.previousWorkerNodeKey);\n }\n else {\n this.nextWorkerNodeKey =\n this.nextWorkerNodeKey === this.pool.workerNodes.length - 1\n ? 0\n : (this.nextWorkerNodeKey ?? this.previousWorkerNodeKey) + 1;\n this.workerNodeVirtualTaskRunTime = 0;\n }\n return this.nextWorkerNodeKey;\n }\n}\n//# sourceMappingURL=weighted-round-robin-worker-choice-strategy.js.map","import { DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS } from '../../utils';\nimport { FairShareWorkerChoiceStrategy } from './fair-share-worker-choice-strategy';\nimport { InterleavedWeightedRoundRobinWorkerChoiceStrategy } from './interleaved-weighted-round-robin-worker-choice-strategy';\nimport { LeastBusyWorkerChoiceStrategy } from './least-busy-worker-choice-strategy';\nimport { LeastUsedWorkerChoiceStrategy } from './least-used-worker-choice-strategy';\nimport { LeastEluWorkerChoiceStrategy } from './least-elu-worker-choice-strategy';\nimport { RoundRobinWorkerChoiceStrategy } from './round-robin-worker-choice-strategy';\nimport { WorkerChoiceStrategies } from './selection-strategies-types';\nimport { WeightedRoundRobinWorkerChoiceStrategy } from './weighted-round-robin-worker-choice-strategy';\n/**\n * The worker choice strategy context.\n *\n * @typeParam Worker - Type of worker.\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n * @typeParam Response - Type of execution response. This can only be structured-cloneable data.\n */\nexport class WorkerChoiceStrategyContext {\n workerChoiceStrategy;\n opts;\n workerChoiceStrategies;\n /**\n * The number of times the worker choice strategy in the context has been retried.\n */\n retriesCount = 0;\n /**\n * Worker choice strategy context constructor.\n *\n * @param pool - The pool instance.\n * @param workerChoiceStrategy - The worker choice strategy.\n * @param opts - The worker choice strategy options.\n */\n constructor(pool, workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN, opts = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS) {\n this.workerChoiceStrategy = workerChoiceStrategy;\n this.opts = opts;\n this.opts = { ...DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS, ...opts };\n this.execute = this.execute.bind(this);\n this.workerChoiceStrategies = new Map([\n [\n WorkerChoiceStrategies.ROUND_ROBIN,\n new (RoundRobinWorkerChoiceStrategy.bind(this))(pool, opts)\n ],\n [\n WorkerChoiceStrategies.LEAST_USED,\n new (LeastUsedWorkerChoiceStrategy.bind(this))(pool, opts)\n ],\n [\n WorkerChoiceStrategies.LEAST_BUSY,\n new (LeastBusyWorkerChoiceStrategy.bind(this))(pool, opts)\n ],\n [\n WorkerChoiceStrategies.LEAST_ELU,\n new (LeastEluWorkerChoiceStrategy.bind(this))(pool, opts)\n ],\n [\n WorkerChoiceStrategies.FAIR_SHARE,\n new (FairShareWorkerChoiceStrategy.bind(this))(pool, opts)\n ],\n [\n WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN,\n new (WeightedRoundRobinWorkerChoiceStrategy.bind(this))(pool, opts)\n ],\n [\n WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN,\n new (InterleavedWeightedRoundRobinWorkerChoiceStrategy.bind(this))(pool, opts)\n ]\n ]);\n }\n /**\n * Gets the strategy policy in the context.\n *\n * @returns The strategy policy.\n */\n getStrategyPolicy() {\n return this.workerChoiceStrategies.get(this.workerChoiceStrategy).strategyPolicy;\n }\n /**\n * Gets the worker choice strategy in the context task statistics requirements.\n *\n * @returns The task statistics requirements.\n */\n getTaskStatisticsRequirements() {\n return this.workerChoiceStrategies.get(this.workerChoiceStrategy).taskStatisticsRequirements;\n }\n /**\n * Sets the worker choice strategy to use in the context.\n *\n * @param workerChoiceStrategy - The worker choice strategy to set.\n */\n setWorkerChoiceStrategy(workerChoiceStrategy) {\n if (this.workerChoiceStrategy !== workerChoiceStrategy) {\n this.workerChoiceStrategy = workerChoiceStrategy;\n }\n this.workerChoiceStrategies.get(this.workerChoiceStrategy)?.reset();\n }\n /**\n * Updates the worker node key in the worker choice strategy in the context internals.\n *\n * @returns `true` if the update is successful, `false` otherwise.\n */\n update(workerNodeKey) {\n return this.workerChoiceStrategies.get(this.workerChoiceStrategy).update(workerNodeKey);\n }\n /**\n * Executes the worker choice strategy in the context algorithm.\n *\n * @returns The key of the worker node.\n * @throws {@link https://nodejs.org/api/errors.html#class-error} If after configured retries the worker node key is null or undefined .\n */\n execute() {\n const workerNodeKey = this.workerChoiceStrategies.get(this.workerChoiceStrategy).choose();\n if (workerNodeKey == null &&\n this.retriesCount < this.opts.retries) {\n this.retriesCount++;\n return this.execute();\n }\n else if (workerNodeKey == null) {\n throw new Error(`Worker node key chosen is null or undefined after ${this.retriesCount} retries`);\n }\n this.retriesCount = 0;\n return workerNodeKey;\n }\n /**\n * Removes the worker node key from the worker choice strategy in the context.\n *\n * @param workerNodeKey - The worker node key.\n * @returns `true` if the removal is successful, `false` otherwise.\n */\n remove(workerNodeKey) {\n return this.workerChoiceStrategies.get(this.workerChoiceStrategy).remove(workerNodeKey);\n }\n /**\n * Sets the worker choice strategies in the context options.\n *\n * @param opts - The worker choice strategy options.\n */\n setOptions(opts) {\n this.opts = { ...DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS, ...opts };\n for (const workerChoiceStrategy of this.workerChoiceStrategies.values()) {\n workerChoiceStrategy.setOptions(opts);\n }\n }\n}\n//# sourceMappingURL=worker-choice-strategy-context.js.map","// Copyright Jerome Benoit. 2021-2023. All Rights Reserved.\nexport const DEFAULT_CIRCULAR_ARRAY_SIZE = 1024;\n/**\n * Array with a maximum length and shifting items when full.\n *\n * @internal\n */\nexport class CircularArray extends Array {\n size;\n constructor(size = DEFAULT_CIRCULAR_ARRAY_SIZE, ...items) {\n super();\n this.checkSize(size);\n this.size = size;\n if (arguments.length > 1) {\n this.push(...items);\n }\n }\n /** @inheritDoc */\n push(...items) {\n const length = super.push(...items);\n if (length > this.size) {\n super.splice(0, length - this.size);\n }\n return this.length;\n }\n /** @inheritDoc */\n unshift(...items) {\n const length = super.unshift(...items);\n if (length > this.size) {\n super.splice(this.size, items.length);\n }\n return this.length;\n }\n /** @inheritDoc */\n concat(...items) {\n const concatenatedCircularArray = super.concat(items);\n concatenatedCircularArray.size = this.size;\n if (concatenatedCircularArray.length > concatenatedCircularArray.size) {\n concatenatedCircularArray.splice(0, concatenatedCircularArray.length - concatenatedCircularArray.size);\n }\n return concatenatedCircularArray;\n }\n /** @inheritDoc */\n splice(start, deleteCount, ...items) {\n let itemsRemoved = [];\n if (arguments.length >= 3 && deleteCount != null) {\n itemsRemoved = super.splice(start, deleteCount, ...items);\n if (this.length > this.size) {\n const itemsOverflowing = super.splice(0, this.length - this.size);\n itemsRemoved = new CircularArray(itemsRemoved.length + itemsOverflowing.length, ...itemsRemoved, ...itemsOverflowing);\n }\n }\n else if (arguments.length === 2) {\n itemsRemoved = super.splice(start, deleteCount);\n }\n else {\n itemsRemoved = super.splice(start);\n }\n return itemsRemoved;\n }\n resize(size) {\n this.checkSize(size);\n if (size === 0) {\n this.length = 0;\n }\n else if (size < this.size) {\n for (let i = size; i < this.size; i++) {\n super.pop();\n }\n }\n this.size = size;\n }\n empty() {\n return this.length === 0;\n }\n full() {\n return this.length === this.size;\n }\n checkSize(size) {\n if (!Number.isSafeInteger(size)) {\n throw new TypeError(`Invalid circular array size: ${size} is not a safe integer`);\n }\n if (size < 0) {\n throw new RangeError(`Invalid circular array size: ${size} < 0`);\n }\n }\n}\n//# sourceMappingURL=circular-array.js.map","// Copyright Jerome Benoit. 2023. All Rights Reserved.\n/**\n * Node.\n *\n * @typeParam T - Type of node data.\n * @internal\n */\nexport class Node {\n data;\n next;\n prev;\n constructor(data) {\n this.data = data;\n }\n}\n/**\n * Deque.\n * Implemented with a doubly linked list.\n *\n * @typeParam T - Type of deque data.\n * @internal\n */\nexport class Deque {\n head;\n tail;\n /** The size of the deque. */\n size;\n /** The maximum size of the deque. */\n maxSize;\n constructor() {\n this.clear();\n }\n /**\n * Appends data to the deque.\n *\n * @param data - Data to append.\n * @returns The new size of the queue.\n */\n push(data) {\n const node = new Node(data);\n if (this.tail == null) {\n this.head = this.tail = node;\n }\n else {\n node.prev = this.tail;\n this.tail = this.tail.next = node;\n }\n return this.incrementSize();\n }\n /**\n * Prepends data to the deque.\n *\n * @param data - Data to prepend.\n * @returns The new size of the queue.\n */\n unshift(data) {\n const node = new Node(data);\n if (this.head == null) {\n this.head = this.tail = node;\n }\n else {\n node.next = this.head;\n this.head = this.head.prev = node;\n }\n return this.incrementSize();\n }\n /**\n * Pops data from the deque.\n *\n * @returns The popped data or `undefined` if the deque is empty.\n */\n pop() {\n if (this.head == null) {\n return undefined;\n }\n const tail = this.tail;\n this.tail = this.tail.prev;\n if (this.tail == null) {\n this.head = undefined;\n }\n else {\n this.tail.next = undefined;\n }\n --this.size;\n return tail?.data;\n }\n /**\n * Shifts data from the deque.\n *\n * @returns The shifted data or `undefined` if the deque is empty.\n */\n shift() {\n if (this.head == null) {\n return undefined;\n }\n const head = this.head;\n this.head = this.head.next;\n if (this.head == null) {\n this.tail = undefined;\n }\n else {\n this.head.prev = undefined;\n }\n --this.size;\n return head?.data;\n }\n /**\n * Peeks at the first data.\n * @returns The first data or `undefined` if the deque is empty.\n */\n peekFirst() {\n return this.head?.data;\n }\n /**\n * Peeks at the last data.\n * @returns The last data or `undefined` if the deque is empty.\n */\n peekLast() {\n return this.tail?.data;\n }\n /**\n * Clears the deque.\n */\n clear() {\n this.head = undefined;\n this.tail = undefined;\n this.size = 0;\n this.maxSize = 0;\n }\n /**\n * Returns an iterator for the deque.\n *\n * @returns An iterator for the deque.\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols\n */\n [Symbol.iterator]() {\n let node = this.head;\n return {\n next: () => {\n if (node == null) {\n return {\n value: undefined,\n done: true\n };\n }\n const ret = {\n value: node.data,\n done: false\n };\n node = node.next;\n return ret;\n }\n };\n }\n /**\n * Returns an backward iterator for the deque.\n *\n * @returns An backward iterator for the deque.\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols\n */\n backward() {\n return {\n [Symbol.iterator]: () => {\n let node = this.tail;\n return {\n next: () => {\n if (node == null) {\n return {\n value: undefined,\n done: true\n };\n }\n const ret = {\n value: node.data,\n done: false\n };\n node = node.prev;\n return ret;\n }\n };\n }\n };\n }\n incrementSize() {\n ++this.size;\n if (this.size > this.maxSize) {\n this.maxSize = this.size;\n }\n return this.size;\n }\n}\n//# sourceMappingURL=deque.js.map","import { MessageChannel } from 'node:worker_threads';\nimport { CircularArray } from '../circular-array';\nimport { DEFAULT_TASK_NAME, EMPTY_FUNCTION, exponentialDelay, getWorkerId, getWorkerType, sleep } from '../utils';\nimport { Deque } from '../deque';\nimport { WorkerTypes } from './worker';\nimport { checkWorkerNodeArguments } from './utils';\n/**\n * Worker node.\n *\n * @typeParam Worker - Type of worker.\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n */\nexport class WorkerNode {\n /** @inheritdoc */\n worker;\n /** @inheritdoc */\n info;\n /** @inheritdoc */\n usage;\n /** @inheritdoc */\n strategyData;\n /** @inheritdoc */\n messageChannel;\n /** @inheritdoc */\n tasksQueueBackPressureSize;\n /** @inheritdoc */\n onBackPressure;\n /** @inheritdoc */\n onEmptyQueue;\n tasksQueue;\n onBackPressureStarted;\n onEmptyQueueCount;\n taskFunctionsUsage;\n /**\n * Constructs a new worker node.\n *\n * @param worker - The worker.\n * @param tasksQueueBackPressureSize - The tasks queue back pressure size.\n */\n constructor(worker, tasksQueueBackPressureSize) {\n checkWorkerNodeArguments(worker, tasksQueueBackPressureSize);\n this.worker = worker;\n this.info = this.initWorkerInfo(worker);\n this.usage = this.initWorkerUsage();\n if (this.info.type === WorkerTypes.thread) {\n this.messageChannel = new MessageChannel();\n }\n this.tasksQueueBackPressureSize = tasksQueueBackPressureSize;\n this.tasksQueue = new Deque();\n this.onBackPressureStarted = false;\n this.onEmptyQueueCount = 0;\n this.taskFunctionsUsage = new Map();\n }\n /** @inheritdoc */\n tasksQueueSize() {\n return this.tasksQueue.size;\n }\n /** @inheritdoc */\n enqueueTask(task) {\n const tasksQueueSize = this.tasksQueue.push(task);\n if (this.onBackPressure != null &&\n this.hasBackPressure() &&\n !this.onBackPressureStarted) {\n this.onBackPressureStarted = true;\n this.onBackPressure(this.info.id);\n this.onBackPressureStarted = false;\n }\n return tasksQueueSize;\n }\n /** @inheritdoc */\n unshiftTask(task) {\n const tasksQueueSize = this.tasksQueue.unshift(task);\n if (this.onBackPressure != null &&\n this.hasBackPressure() &&\n !this.onBackPressureStarted) {\n this.onBackPressureStarted = true;\n this.onBackPressure(this.info.id);\n this.onBackPressureStarted = false;\n }\n return tasksQueueSize;\n }\n /** @inheritdoc */\n dequeueTask() {\n const task = this.tasksQueue.shift();\n if (this.onEmptyQueue != null &&\n this.tasksQueue.size === 0 &&\n this.onEmptyQueueCount === 0) {\n this.startOnEmptyQueue().catch(EMPTY_FUNCTION);\n }\n return task;\n }\n /** @inheritdoc */\n popTask() {\n const task = this.tasksQueue.pop();\n if (this.onEmptyQueue != null &&\n this.tasksQueue.size === 0 &&\n this.onEmptyQueueCount === 0) {\n this.startOnEmptyQueue().catch(EMPTY_FUNCTION);\n }\n return task;\n }\n /** @inheritdoc */\n clearTasksQueue() {\n this.tasksQueue.clear();\n }\n /** @inheritdoc */\n hasBackPressure() {\n return this.tasksQueue.size >= this.tasksQueueBackPressureSize;\n }\n /** @inheritdoc */\n resetUsage() {\n this.usage = this.initWorkerUsage();\n this.taskFunctionsUsage.clear();\n }\n /** @inheritdoc */\n closeChannel() {\n if (this.messageChannel != null) {\n this.messageChannel?.port1.unref();\n this.messageChannel?.port2.unref();\n this.messageChannel?.port1.close();\n this.messageChannel?.port2.close();\n delete this.messageChannel;\n }\n }\n /** @inheritdoc */\n getTaskFunctionWorkerUsage(name) {\n if (!Array.isArray(this.info.taskFunctionNames)) {\n throw new Error(`Cannot get task function worker usage for task function name '${name}' when task function names list is not yet defined`);\n }\n if (Array.isArray(this.info.taskFunctionNames) &&\n this.info.taskFunctionNames.length < 3) {\n throw new Error(`Cannot get task function worker usage for task function name '${name}' when task function names list has less than 3 elements`);\n }\n if (name === DEFAULT_TASK_NAME) {\n name = this.info.taskFunctionNames[1];\n }\n if (!this.taskFunctionsUsage.has(name)) {\n this.taskFunctionsUsage.set(name, this.initTaskFunctionWorkerUsage(name));\n }\n return this.taskFunctionsUsage.get(name);\n }\n /** @inheritdoc */\n deleteTaskFunctionWorkerUsage(name) {\n return this.taskFunctionsUsage.delete(name);\n }\n async startOnEmptyQueue() {\n if (this.onEmptyQueueCount > 0 &&\n (this.usage.tasks.executing > 0 || this.tasksQueue.size > 0)) {\n this.onEmptyQueueCount = 0;\n return;\n }\n ++this.onEmptyQueueCount;\n this.onEmptyQueue?.(this.info.id);\n await sleep(exponentialDelay(this.onEmptyQueueCount));\n await this.startOnEmptyQueue();\n }\n initWorkerInfo(worker) {\n return {\n id: getWorkerId(worker),\n type: getWorkerType(worker),\n dynamic: false,\n ready: false\n };\n }\n initWorkerUsage() {\n const getTasksQueueSize = () => {\n return this.tasksQueue.size;\n };\n const getTasksQueueMaxSize = () => {\n return this.tasksQueue.maxSize;\n };\n return {\n tasks: {\n executed: 0,\n executing: 0,\n get queued() {\n return getTasksQueueSize();\n },\n get maxQueued() {\n return getTasksQueueMaxSize();\n },\n stolen: 0,\n failed: 0\n },\n runTime: {\n history: new CircularArray()\n },\n waitTime: {\n history: new CircularArray()\n },\n elu: {\n idle: {\n history: new CircularArray()\n },\n active: {\n history: new CircularArray()\n }\n }\n };\n }\n initTaskFunctionWorkerUsage(name) {\n const getTaskFunctionQueueSize = () => {\n let taskFunctionQueueSize = 0;\n for (const task of this.tasksQueue) {\n if ((task.name === DEFAULT_TASK_NAME &&\n name === this.info.taskFunctionNames[1]) ||\n (task.name !== DEFAULT_TASK_NAME && name === task.name)) {\n ++taskFunctionQueueSize;\n }\n }\n return taskFunctionQueueSize;\n };\n return {\n tasks: {\n executed: 0,\n executing: 0,\n get queued() {\n return getTaskFunctionQueueSize();\n },\n stolen: 0,\n failed: 0\n },\n runTime: {\n history: new CircularArray()\n },\n waitTime: {\n history: new CircularArray()\n },\n elu: {\n idle: {\n history: new CircularArray()\n },\n active: {\n history: new CircularArray()\n }\n }\n };\n }\n}\n//# sourceMappingURL=worker-node.js.map","import { randomUUID } from 'node:crypto';\nimport { performance } from 'node:perf_hooks';\nimport { EventEmitterAsyncResource } from 'node:events';\nimport { DEFAULT_TASK_NAME, DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS, EMPTY_FUNCTION, average, isKillBehavior, isPlainObject, max, median, min, round } from '../utils';\nimport { KillBehaviors } from '../worker/worker-options';\nimport { PoolEvents, PoolTypes } from './pool';\nimport { Measurements, WorkerChoiceStrategies } from './selection-strategies/selection-strategies-types';\nimport { WorkerChoiceStrategyContext } from './selection-strategies/worker-choice-strategy-context';\nimport { version } from './version';\nimport { WorkerNode } from './worker-node';\nimport { checkFilePath, checkValidTasksQueueOptions, checkValidWorkerChoiceStrategy, updateMeasurementStatistics } from './utils';\n/**\n * Base class that implements some shared logic for all poolifier pools.\n *\n * @typeParam Worker - Type of worker which manages this pool.\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n * @typeParam Response - Type of execution response. This can only be structured-cloneable data.\n */\nexport class AbstractPool {\n numberOfWorkers;\n filePath;\n opts;\n /** @inheritDoc */\n workerNodes = [];\n /** @inheritDoc */\n emitter;\n /**\n * The task execution response promise map:\n * - `key`: The message id of each submitted task.\n * - `value`: An object that contains the worker, the execution response promise resolve and reject callbacks.\n *\n * When we receive a message from the worker, we get a map entry with the promise resolve/reject bound to the message id.\n */\n promiseResponseMap = new Map();\n /**\n * Worker choice strategy context referencing a worker choice algorithm implementation.\n */\n workerChoiceStrategyContext;\n /**\n * Dynamic pool maximum size property placeholder.\n */\n max;\n /**\n * The task functions added at runtime map:\n * - `key`: The task function name.\n * - `value`: The task function itself.\n */\n taskFunctions;\n /**\n * Whether the pool is started or not.\n */\n started;\n /**\n * Whether the pool is starting or not.\n */\n starting;\n /**\n * The start timestamp of the pool.\n */\n startTimestamp;\n /**\n * Constructs a new poolifier pool.\n *\n * @param numberOfWorkers - Number of workers that this pool should manage.\n * @param filePath - Path to the worker file.\n * @param opts - Options for the pool.\n */\n constructor(numberOfWorkers, filePath, opts) {\n this.numberOfWorkers = numberOfWorkers;\n this.filePath = filePath;\n this.opts = opts;\n if (!this.isMain()) {\n throw new Error('Cannot start a pool from a worker with the same type as the pool');\n }\n checkFilePath(this.filePath);\n this.checkNumberOfWorkers(this.numberOfWorkers);\n this.checkPoolOptions(this.opts);\n this.chooseWorkerNode = this.chooseWorkerNode.bind(this);\n this.executeTask = this.executeTask.bind(this);\n this.enqueueTask = this.enqueueTask.bind(this);\n if (this.opts.enableEvents === true) {\n this.initializeEventEmitter();\n }\n this.workerChoiceStrategyContext = new WorkerChoiceStrategyContext(this, this.opts.workerChoiceStrategy, this.opts.workerChoiceStrategyOptions);\n this.setupHook();\n this.taskFunctions = new Map();\n this.started = false;\n this.starting = false;\n if (this.opts.startWorkers === true) {\n this.start();\n }\n this.startTimestamp = performance.now();\n }\n checkNumberOfWorkers(numberOfWorkers) {\n if (numberOfWorkers == null) {\n throw new Error('Cannot instantiate a pool without specifying the number of workers');\n }\n else if (!Number.isSafeInteger(numberOfWorkers)) {\n throw new TypeError('Cannot instantiate a pool with a non safe integer number of workers');\n }\n else if (numberOfWorkers < 0) {\n throw new RangeError('Cannot instantiate a pool with a negative number of workers');\n }\n else if (this.type === PoolTypes.fixed && numberOfWorkers === 0) {\n throw new RangeError('Cannot instantiate a fixed pool with zero worker');\n }\n }\n checkPoolOptions(opts) {\n if (isPlainObject(opts)) {\n this.opts.startWorkers = opts.startWorkers ?? true;\n checkValidWorkerChoiceStrategy(opts.workerChoiceStrategy);\n this.opts.workerChoiceStrategy =\n opts.workerChoiceStrategy ?? WorkerChoiceStrategies.ROUND_ROBIN;\n this.checkValidWorkerChoiceStrategyOptions(opts.workerChoiceStrategyOptions);\n this.opts.workerChoiceStrategyOptions = {\n ...DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS,\n ...opts.workerChoiceStrategyOptions\n };\n this.opts.restartWorkerOnError = opts.restartWorkerOnError ?? true;\n this.opts.enableEvents = opts.enableEvents ?? true;\n this.opts.enableTasksQueue = opts.enableTasksQueue ?? false;\n if (this.opts.enableTasksQueue) {\n checkValidTasksQueueOptions(opts.tasksQueueOptions);\n this.opts.tasksQueueOptions = this.buildTasksQueueOptions(opts.tasksQueueOptions);\n }\n }\n else {\n throw new TypeError('Invalid pool options: must be a plain object');\n }\n }\n checkValidWorkerChoiceStrategyOptions(workerChoiceStrategyOptions) {\n if (workerChoiceStrategyOptions != null &&\n !isPlainObject(workerChoiceStrategyOptions)) {\n throw new TypeError('Invalid worker choice strategy options: must be a plain object');\n }\n if (workerChoiceStrategyOptions?.retries != null &&\n !Number.isSafeInteger(workerChoiceStrategyOptions.retries)) {\n throw new TypeError('Invalid worker choice strategy options: retries must be an integer');\n }\n if (workerChoiceStrategyOptions?.retries != null &&\n workerChoiceStrategyOptions.retries < 0) {\n throw new RangeError(`Invalid worker choice strategy options: retries '${workerChoiceStrategyOptions.retries}' must be greater or equal than zero`);\n }\n if (workerChoiceStrategyOptions?.weights != null &&\n Object.keys(workerChoiceStrategyOptions.weights).length !== this.maxSize) {\n throw new Error('Invalid worker choice strategy options: must have a weight for each worker node');\n }\n if (workerChoiceStrategyOptions?.measurement != null &&\n !Object.values(Measurements).includes(workerChoiceStrategyOptions.measurement)) {\n throw new Error(`Invalid worker choice strategy options: invalid measurement '${workerChoiceStrategyOptions.measurement}'`);\n }\n }\n initializeEventEmitter() {\n this.emitter = new EventEmitterAsyncResource({\n name: `poolifier:${this.type}-${this.worker}-pool`\n });\n }\n /** @inheritDoc */\n get info() {\n return {\n version,\n type: this.type,\n worker: this.worker,\n started: this.started,\n ready: this.ready,\n strategy: this.opts.workerChoiceStrategy,\n minSize: this.minSize,\n maxSize: this.maxSize,\n ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()\n .runTime.aggregate &&\n this.workerChoiceStrategyContext.getTaskStatisticsRequirements()\n .waitTime.aggregate && { utilization: round(this.utilization) }),\n workerNodes: this.workerNodes.length,\n idleWorkerNodes: this.workerNodes.reduce((accumulator, workerNode) => workerNode.usage.tasks.executing === 0\n ? accumulator + 1\n : accumulator, 0),\n busyWorkerNodes: this.workerNodes.reduce((accumulator, workerNode) => workerNode.usage.tasks.executing > 0 ? accumulator + 1 : accumulator, 0),\n executedTasks: this.workerNodes.reduce((accumulator, workerNode) => accumulator + workerNode.usage.tasks.executed, 0),\n executingTasks: this.workerNodes.reduce((accumulator, workerNode) => accumulator + workerNode.usage.tasks.executing, 0),\n ...(this.opts.enableTasksQueue === true && {\n queuedTasks: this.workerNodes.reduce((accumulator, workerNode) => accumulator + workerNode.usage.tasks.queued, 0)\n }),\n ...(this.opts.enableTasksQueue === true && {\n maxQueuedTasks: this.workerNodes.reduce((accumulator, workerNode) => accumulator + (workerNode.usage.tasks?.maxQueued ?? 0), 0)\n }),\n ...(this.opts.enableTasksQueue === true && {\n backPressure: this.hasBackPressure()\n }),\n ...(this.opts.enableTasksQueue === true && {\n stolenTasks: this.workerNodes.reduce((accumulator, workerNode) => accumulator + workerNode.usage.tasks.stolen, 0)\n }),\n failedTasks: this.workerNodes.reduce((accumulator, workerNode) => accumulator + workerNode.usage.tasks.failed, 0),\n ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()\n .runTime.aggregate && {\n runTime: {\n minimum: round(min(...this.workerNodes.map(workerNode => workerNode.usage.runTime?.minimum ?? Infinity))),\n maximum: round(max(...this.workerNodes.map(workerNode => workerNode.usage.runTime?.maximum ?? -Infinity))),\n ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()\n .runTime.average && {\n average: round(average(this.workerNodes.reduce((accumulator, workerNode) => accumulator.concat(workerNode.usage.runTime.history), [])))\n }),\n ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()\n .runTime.median && {\n median: round(median(this.workerNodes.reduce((accumulator, workerNode) => accumulator.concat(workerNode.usage.runTime.history), [])))\n })\n }\n }),\n ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()\n .waitTime.aggregate && {\n waitTime: {\n minimum: round(min(...this.workerNodes.map(workerNode => workerNode.usage.waitTime?.minimum ?? Infinity))),\n maximum: round(max(...this.workerNodes.map(workerNode => workerNode.usage.waitTime?.maximum ?? -Infinity))),\n ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()\n .waitTime.average && {\n average: round(average(this.workerNodes.reduce((accumulator, workerNode) => accumulator.concat(workerNode.usage.waitTime.history), [])))\n }),\n ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()\n .waitTime.median && {\n median: round(median(this.workerNodes.reduce((accumulator, workerNode) => accumulator.concat(workerNode.usage.waitTime.history), [])))\n })\n }\n })\n };\n }\n /**\n * The pool readiness boolean status.\n */\n get ready() {\n return (this.workerNodes.reduce((accumulator, workerNode) => !workerNode.info.dynamic && workerNode.info.ready\n ? accumulator + 1\n : accumulator, 0) >= this.minSize);\n }\n /**\n * The approximate pool utilization.\n *\n * @returns The pool utilization.\n */\n get utilization() {\n const poolTimeCapacity = (performance.now() - this.startTimestamp) * this.maxSize;\n const totalTasksRunTime = this.workerNodes.reduce((accumulator, workerNode) => accumulator + (workerNode.usage.runTime?.aggregate ?? 0), 0);\n const totalTasksWaitTime = this.workerNodes.reduce((accumulator, workerNode) => accumulator + (workerNode.usage.waitTime?.aggregate ?? 0), 0);\n return (totalTasksRunTime + totalTasksWaitTime) / poolTimeCapacity;\n }\n /**\n * The pool minimum size.\n */\n get minSize() {\n return this.numberOfWorkers;\n }\n /**\n * The pool maximum size.\n */\n get maxSize() {\n return this.max ?? this.numberOfWorkers;\n }\n /**\n * Checks if the worker id sent in the received message from a worker is valid.\n *\n * @param message - The received message.\n * @throws {@link https://nodejs.org/api/errors.html#class-error} If the worker id is invalid.\n */\n checkMessageWorkerId(message) {\n if (message.workerId == null) {\n throw new Error('Worker message received without worker id');\n }\n else if (message.workerId != null &&\n this.getWorkerNodeKeyByWorkerId(message.workerId) === -1) {\n throw new Error(`Worker message received from unknown worker '${message.workerId}'`);\n }\n }\n /**\n * Gets the given worker its worker node key.\n *\n * @param worker - The worker.\n * @returns The worker node key if found in the pool worker nodes, `-1` otherwise.\n */\n getWorkerNodeKeyByWorker(worker) {\n return this.workerNodes.findIndex(workerNode => workerNode.worker === worker);\n }\n /**\n * Gets the worker node key given its worker id.\n *\n * @param workerId - The worker id.\n * @returns The worker node key if the worker id is found in the pool worker nodes, `-1` otherwise.\n */\n getWorkerNodeKeyByWorkerId(workerId) {\n return this.workerNodes.findIndex(workerNode => workerNode.info.id === workerId);\n }\n /** @inheritDoc */\n setWorkerChoiceStrategy(workerChoiceStrategy, workerChoiceStrategyOptions) {\n checkValidWorkerChoiceStrategy(workerChoiceStrategy);\n this.opts.workerChoiceStrategy = workerChoiceStrategy;\n this.workerChoiceStrategyContext.setWorkerChoiceStrategy(this.opts.workerChoiceStrategy);\n if (workerChoiceStrategyOptions != null) {\n this.setWorkerChoiceStrategyOptions(workerChoiceStrategyOptions);\n }\n for (const [workerNodeKey, workerNode] of this.workerNodes.entries()) {\n workerNode.resetUsage();\n this.sendStatisticsMessageToWorker(workerNodeKey);\n }\n }\n /** @inheritDoc */\n setWorkerChoiceStrategyOptions(workerChoiceStrategyOptions) {\n this.checkValidWorkerChoiceStrategyOptions(workerChoiceStrategyOptions);\n this.opts.workerChoiceStrategyOptions = {\n ...DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS,\n ...workerChoiceStrategyOptions\n };\n this.workerChoiceStrategyContext.setOptions(this.opts.workerChoiceStrategyOptions);\n }\n /** @inheritDoc */\n enableTasksQueue(enable, tasksQueueOptions) {\n if (this.opts.enableTasksQueue === true && !enable) {\n this.unsetTaskStealing();\n this.unsetTasksStealingOnBackPressure();\n this.flushTasksQueues();\n }\n this.opts.enableTasksQueue = enable;\n this.setTasksQueueOptions(tasksQueueOptions);\n }\n /** @inheritDoc */\n setTasksQueueOptions(tasksQueueOptions) {\n if (this.opts.enableTasksQueue === true) {\n checkValidTasksQueueOptions(tasksQueueOptions);\n this.opts.tasksQueueOptions =\n this.buildTasksQueueOptions(tasksQueueOptions);\n this.setTasksQueueSize(this.opts.tasksQueueOptions.size);\n if (this.opts.tasksQueueOptions.taskStealing === true) {\n this.setTaskStealing();\n }\n else {\n this.unsetTaskStealing();\n }\n if (this.opts.tasksQueueOptions.tasksStealingOnBackPressure === true) {\n this.setTasksStealingOnBackPressure();\n }\n else {\n this.unsetTasksStealingOnBackPressure();\n }\n }\n else if (this.opts.tasksQueueOptions != null) {\n delete this.opts.tasksQueueOptions;\n }\n }\n buildTasksQueueOptions(tasksQueueOptions) {\n return {\n ...{\n size: Math.pow(this.maxSize, 2),\n concurrency: 1,\n taskStealing: true,\n tasksStealingOnBackPressure: true\n },\n ...tasksQueueOptions\n };\n }\n setTasksQueueSize(size) {\n for (const workerNode of this.workerNodes) {\n workerNode.tasksQueueBackPressureSize = size;\n }\n }\n setTaskStealing() {\n for (const [workerNodeKey] of this.workerNodes.entries()) {\n this.workerNodes[workerNodeKey].onEmptyQueue =\n this.taskStealingOnEmptyQueue.bind(this);\n }\n }\n unsetTaskStealing() {\n for (const [workerNodeKey] of this.workerNodes.entries()) {\n delete this.workerNodes[workerNodeKey].onEmptyQueue;\n }\n }\n setTasksStealingOnBackPressure() {\n for (const [workerNodeKey] of this.workerNodes.entries()) {\n this.workerNodes[workerNodeKey].onBackPressure =\n this.tasksStealingOnBackPressure.bind(this);\n }\n }\n unsetTasksStealingOnBackPressure() {\n for (const [workerNodeKey] of this.workerNodes.entries()) {\n delete this.workerNodes[workerNodeKey].onBackPressure;\n }\n }\n /**\n * Whether the pool is full or not.\n *\n * The pool filling boolean status.\n */\n get full() {\n return this.workerNodes.length >= this.maxSize;\n }\n /**\n * Whether worker nodes are executing concurrently their tasks quota or not.\n *\n * @returns Worker nodes busyness boolean status.\n */\n internalBusy() {\n if (this.opts.enableTasksQueue === true) {\n return (this.workerNodes.findIndex(workerNode => workerNode.info.ready &&\n workerNode.usage.tasks.executing <\n this.opts.tasksQueueOptions?.concurrency) === -1);\n }\n return (this.workerNodes.findIndex(workerNode => workerNode.info.ready && workerNode.usage.tasks.executing === 0) === -1);\n }\n async sendTaskFunctionOperationToWorker(workerNodeKey, message) {\n return await new Promise((resolve, reject) => {\n const taskFunctionOperationListener = (message) => {\n this.checkMessageWorkerId(message);\n const workerId = this.getWorkerInfo(workerNodeKey).id;\n if (message.taskFunctionOperationStatus != null &&\n message.workerId === workerId) {\n if (message.taskFunctionOperationStatus) {\n resolve(true);\n }\n else if (!message.taskFunctionOperationStatus) {\n reject(new Error(`Task function operation '${message.taskFunctionOperation}' failed on worker ${message.workerId} with error: '${message.workerError?.message}'`));\n }\n this.deregisterWorkerMessageListener(this.getWorkerNodeKeyByWorkerId(message.workerId), taskFunctionOperationListener);\n }\n };\n this.registerWorkerMessageListener(workerNodeKey, taskFunctionOperationListener);\n this.sendToWorker(workerNodeKey, message);\n });\n }\n async sendTaskFunctionOperationToWorkers(message) {\n return await new Promise((resolve, reject) => {\n const responsesReceived = new Array();\n const taskFunctionOperationsListener = (message) => {\n this.checkMessageWorkerId(message);\n if (message.taskFunctionOperationStatus != null) {\n responsesReceived.push(message);\n if (responsesReceived.length === this.workerNodes.length) {\n if (responsesReceived.every(message => message.taskFunctionOperationStatus === true)) {\n resolve(true);\n }\n else if (responsesReceived.some(message => message.taskFunctionOperationStatus === false)) {\n const errorResponse = responsesReceived.find(response => response.taskFunctionOperationStatus === false);\n reject(new Error(`Task function operation '${message.taskFunctionOperation}' failed on worker ${errorResponse?.workerId} with error: '${errorResponse?.workerError?.message}'`));\n }\n this.deregisterWorkerMessageListener(this.getWorkerNodeKeyByWorkerId(message.workerId), taskFunctionOperationsListener);\n }\n }\n };\n for (const [workerNodeKey] of this.workerNodes.entries()) {\n this.registerWorkerMessageListener(workerNodeKey, taskFunctionOperationsListener);\n this.sendToWorker(workerNodeKey, message);\n }\n });\n }\n /** @inheritDoc */\n hasTaskFunction(name) {\n for (const workerNode of this.workerNodes) {\n if (Array.isArray(workerNode.info.taskFunctionNames) &&\n workerNode.info.taskFunctionNames.includes(name)) {\n return true;\n }\n }\n return false;\n }\n /** @inheritDoc */\n async addTaskFunction(name, fn) {\n if (typeof name !== 'string') {\n throw new TypeError('name argument must be a string');\n }\n if (typeof name === 'string' && name.trim().length === 0) {\n throw new TypeError('name argument must not be an empty string');\n }\n if (typeof fn !== 'function') {\n throw new TypeError('fn argument must be a function');\n }\n const opResult = await this.sendTaskFunctionOperationToWorkers({\n taskFunctionOperation: 'add',\n taskFunctionName: name,\n taskFunction: fn.toString()\n });\n this.taskFunctions.set(name, fn);\n return opResult;\n }\n /** @inheritDoc */\n async removeTaskFunction(name) {\n if (!this.taskFunctions.has(name)) {\n throw new Error('Cannot remove a task function not handled on the pool side');\n }\n const opResult = await this.sendTaskFunctionOperationToWorkers({\n taskFunctionOperation: 'remove',\n taskFunctionName: name\n });\n this.deleteTaskFunctionWorkerUsages(name);\n this.taskFunctions.delete(name);\n return opResult;\n }\n /** @inheritDoc */\n listTaskFunctionNames() {\n for (const workerNode of this.workerNodes) {\n if (Array.isArray(workerNode.info.taskFunctionNames) &&\n workerNode.info.taskFunctionNames.length > 0) {\n return workerNode.info.taskFunctionNames;\n }\n }\n return [];\n }\n /** @inheritDoc */\n async setDefaultTaskFunction(name) {\n return await this.sendTaskFunctionOperationToWorkers({\n taskFunctionOperation: 'default',\n taskFunctionName: name\n });\n }\n deleteTaskFunctionWorkerUsages(name) {\n for (const workerNode of this.workerNodes) {\n workerNode.deleteTaskFunctionWorkerUsage(name);\n }\n }\n shallExecuteTask(workerNodeKey) {\n return (this.tasksQueueSize(workerNodeKey) === 0 &&\n this.workerNodes[workerNodeKey].usage.tasks.executing <\n this.opts.tasksQueueOptions?.concurrency);\n }\n /** @inheritDoc */\n async execute(data, name, transferList) {\n return await new Promise((resolve, reject) => {\n if (!this.started) {\n reject(new Error('Cannot execute a task on not started pool'));\n return;\n }\n if (name != null && typeof name !== 'string') {\n reject(new TypeError('name argument must be a string'));\n return;\n }\n if (name != null &&\n typeof name === 'string' &&\n name.trim().length === 0) {\n reject(new TypeError('name argument must not be an empty string'));\n return;\n }\n if (transferList != null && !Array.isArray(transferList)) {\n reject(new TypeError('transferList argument must be an array'));\n return;\n }\n const timestamp = performance.now();\n const workerNodeKey = this.chooseWorkerNode();\n const task = {\n name: name ?? DEFAULT_TASK_NAME,\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n data: data ?? {},\n transferList,\n timestamp,\n taskId: randomUUID()\n };\n this.promiseResponseMap.set(task.taskId, {\n resolve,\n reject,\n workerNodeKey\n });\n if (this.opts.enableTasksQueue === false ||\n (this.opts.enableTasksQueue === true &&\n this.shallExecuteTask(workerNodeKey))) {\n this.executeTask(workerNodeKey, task);\n }\n else {\n this.enqueueTask(workerNodeKey, task);\n }\n });\n }\n /** @inheritdoc */\n start() {\n this.starting = true;\n while (this.workerNodes.reduce((accumulator, workerNode) => !workerNode.info.dynamic ? accumulator + 1 : accumulator, 0) < this.numberOfWorkers) {\n this.createAndSetupWorkerNode();\n }\n this.starting = false;\n this.started = true;\n }\n /** @inheritDoc */\n async destroy() {\n await Promise.all(this.workerNodes.map(async (_, workerNodeKey) => {\n await this.destroyWorkerNode(workerNodeKey);\n }));\n this.emitter?.emit(PoolEvents.destroy, this.info);\n if (this.emitter instanceof EventEmitterAsyncResource) {\n this.emitter?.emitDestroy();\n }\n this.started = false;\n }\n async sendKillMessageToWorker(workerNodeKey) {\n await new Promise((resolve, reject) => {\n const killMessageListener = (message) => {\n this.checkMessageWorkerId(message);\n if (message.kill === 'success') {\n resolve();\n }\n else if (message.kill === 'failure') {\n reject(new Error(`Kill message handling failed on worker ${message.workerId}`));\n }\n };\n this.registerWorkerMessageListener(workerNodeKey, killMessageListener);\n this.sendToWorker(workerNodeKey, { kill: true });\n });\n }\n /**\n * Setup hook to execute code before worker nodes are created in the abstract constructor.\n * Can be overridden.\n *\n * @virtual\n */\n setupHook() {\n /* Intentionally empty */\n }\n /**\n * Hook executed before the worker task execution.\n * Can be overridden.\n *\n * @param workerNodeKey - The worker node key.\n * @param task - The task to execute.\n */\n beforeTaskExecutionHook(workerNodeKey, task) {\n if (this.workerNodes[workerNodeKey]?.usage != null) {\n const workerUsage = this.workerNodes[workerNodeKey].usage;\n ++workerUsage.tasks.executing;\n this.updateWaitTimeWorkerUsage(workerUsage, task);\n }\n if (this.shallUpdateTaskFunctionWorkerUsage(workerNodeKey) &&\n this.workerNodes[workerNodeKey].getTaskFunctionWorkerUsage(task.name) != null) {\n const taskFunctionWorkerUsage = this.workerNodes[workerNodeKey].getTaskFunctionWorkerUsage(task.name);\n ++taskFunctionWorkerUsage.tasks.executing;\n this.updateWaitTimeWorkerUsage(taskFunctionWorkerUsage, task);\n }\n }\n /**\n * Hook executed after the worker task execution.\n * Can be overridden.\n *\n * @param workerNodeKey - The worker node key.\n * @param message - The received message.\n */\n afterTaskExecutionHook(workerNodeKey, message) {\n if (this.workerNodes[workerNodeKey]?.usage != null) {\n const workerUsage = this.workerNodes[workerNodeKey].usage;\n this.updateTaskStatisticsWorkerUsage(workerUsage, message);\n this.updateRunTimeWorkerUsage(workerUsage, message);\n this.updateEluWorkerUsage(workerUsage, message);\n }\n if (this.shallUpdateTaskFunctionWorkerUsage(workerNodeKey) &&\n this.workerNodes[workerNodeKey].getTaskFunctionWorkerUsage(message.taskPerformance?.name) != null) {\n const taskFunctionWorkerUsage = this.workerNodes[workerNodeKey].getTaskFunctionWorkerUsage(message.taskPerformance?.name);\n this.updateTaskStatisticsWorkerUsage(taskFunctionWorkerUsage, message);\n this.updateRunTimeWorkerUsage(taskFunctionWorkerUsage, message);\n this.updateEluWorkerUsage(taskFunctionWorkerUsage, message);\n }\n }\n /**\n * Whether the worker node shall update its task function worker usage or not.\n *\n * @param workerNodeKey - The worker node key.\n * @returns `true` if the worker node shall update its task function worker usage, `false` otherwise.\n */\n shallUpdateTaskFunctionWorkerUsage(workerNodeKey) {\n const workerInfo = this.getWorkerInfo(workerNodeKey);\n return (workerInfo != null &&\n Array.isArray(workerInfo.taskFunctionNames) &&\n workerInfo.taskFunctionNames.length > 2);\n }\n updateTaskStatisticsWorkerUsage(workerUsage, message) {\n const workerTaskStatistics = workerUsage.tasks;\n if (workerTaskStatistics.executing != null &&\n workerTaskStatistics.executing > 0) {\n --workerTaskStatistics.executing;\n }\n if (message.workerError == null) {\n ++workerTaskStatistics.executed;\n }\n else {\n ++workerTaskStatistics.failed;\n }\n }\n updateRunTimeWorkerUsage(workerUsage, message) {\n if (message.workerError != null) {\n return;\n }\n updateMeasurementStatistics(workerUsage.runTime, this.workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime, message.taskPerformance?.runTime ?? 0);\n }\n updateWaitTimeWorkerUsage(workerUsage, task) {\n const timestamp = performance.now();\n const taskWaitTime = timestamp - (task.timestamp ?? timestamp);\n updateMeasurementStatistics(workerUsage.waitTime, this.workerChoiceStrategyContext.getTaskStatisticsRequirements().waitTime, taskWaitTime);\n }\n updateEluWorkerUsage(workerUsage, message) {\n if (message.workerError != null) {\n return;\n }\n const eluTaskStatisticsRequirements = this.workerChoiceStrategyContext.getTaskStatisticsRequirements().elu;\n updateMeasurementStatistics(workerUsage.elu.active, eluTaskStatisticsRequirements, message.taskPerformance?.elu?.active ?? 0);\n updateMeasurementStatistics(workerUsage.elu.idle, eluTaskStatisticsRequirements, message.taskPerformance?.elu?.idle ?? 0);\n if (eluTaskStatisticsRequirements.aggregate) {\n if (message.taskPerformance?.elu != null) {\n if (workerUsage.elu.utilization != null) {\n workerUsage.elu.utilization =\n (workerUsage.elu.utilization +\n message.taskPerformance.elu.utilization) /\n 2;\n }\n else {\n workerUsage.elu.utilization = message.taskPerformance.elu.utilization;\n }\n }\n }\n }\n /**\n * Chooses a worker node for the next task.\n *\n * The default worker choice strategy uses a round robin algorithm to distribute the tasks.\n *\n * @returns The chosen worker node key\n */\n chooseWorkerNode() {\n if (this.shallCreateDynamicWorker()) {\n const workerNodeKey = this.createAndSetupDynamicWorkerNode();\n if (this.workerChoiceStrategyContext.getStrategyPolicy().dynamicWorkerUsage) {\n return workerNodeKey;\n }\n }\n return this.workerChoiceStrategyContext.execute();\n }\n /**\n * Conditions for dynamic worker creation.\n *\n * @returns Whether to create a dynamic worker or not.\n */\n shallCreateDynamicWorker() {\n return this.type === PoolTypes.dynamic && !this.full && this.internalBusy();\n }\n /**\n * Creates a new, completely set up worker node.\n *\n * @returns New, completely set up worker node key.\n */\n createAndSetupWorkerNode() {\n const worker = this.createWorker();\n worker.on('online', this.opts.onlineHandler ?? EMPTY_FUNCTION);\n worker.on('message', this.opts.messageHandler ?? EMPTY_FUNCTION);\n worker.on('error', this.opts.errorHandler ?? EMPTY_FUNCTION);\n worker.on('error', error => {\n const workerNodeKey = this.getWorkerNodeKeyByWorker(worker);\n const workerInfo = this.getWorkerInfo(workerNodeKey);\n workerInfo.ready = false;\n this.workerNodes[workerNodeKey].closeChannel();\n this.emitter?.emit(PoolEvents.error, error);\n if (this.started &&\n !this.starting &&\n this.opts.restartWorkerOnError === true) {\n if (workerInfo.dynamic) {\n this.createAndSetupDynamicWorkerNode();\n }\n else {\n this.createAndSetupWorkerNode();\n }\n }\n if (this.started && this.opts.enableTasksQueue === true) {\n this.redistributeQueuedTasks(workerNodeKey);\n }\n });\n worker.on('exit', this.opts.exitHandler ?? EMPTY_FUNCTION);\n worker.once('exit', () => {\n this.removeWorkerNode(worker);\n });\n const workerNodeKey = this.addWorkerNode(worker);\n this.afterWorkerNodeSetup(workerNodeKey);\n return workerNodeKey;\n }\n /**\n * Creates a new, completely set up dynamic worker node.\n *\n * @returns New, completely set up dynamic worker node key.\n */\n createAndSetupDynamicWorkerNode() {\n const workerNodeKey = this.createAndSetupWorkerNode();\n this.registerWorkerMessageListener(workerNodeKey, message => {\n this.checkMessageWorkerId(message);\n const localWorkerNodeKey = this.getWorkerNodeKeyByWorkerId(message.workerId);\n const workerUsage = this.workerNodes[localWorkerNodeKey].usage;\n // Kill message received from worker\n if (isKillBehavior(KillBehaviors.HARD, message.kill) ||\n (isKillBehavior(KillBehaviors.SOFT, message.kill) &&\n ((this.opts.enableTasksQueue === false &&\n workerUsage.tasks.executing === 0) ||\n (this.opts.enableTasksQueue === true &&\n workerUsage.tasks.executing === 0 &&\n this.tasksQueueSize(localWorkerNodeKey) === 0)))) {\n this.destroyWorkerNode(localWorkerNodeKey).catch(error => {\n this.emitter?.emit(PoolEvents.error, error);\n });\n }\n });\n const workerInfo = this.getWorkerInfo(workerNodeKey);\n this.sendToWorker(workerNodeKey, {\n checkActive: true\n });\n if (this.taskFunctions.size > 0) {\n for (const [taskFunctionName, taskFunction] of this.taskFunctions) {\n this.sendTaskFunctionOperationToWorker(workerNodeKey, {\n taskFunctionOperation: 'add',\n taskFunctionName,\n taskFunction: taskFunction.toString()\n }).catch(error => {\n this.emitter?.emit(PoolEvents.error, error);\n });\n }\n }\n workerInfo.dynamic = true;\n if (this.workerChoiceStrategyContext.getStrategyPolicy().dynamicWorkerReady ||\n this.workerChoiceStrategyContext.getStrategyPolicy().dynamicWorkerUsage) {\n workerInfo.ready = true;\n }\n this.checkAndEmitDynamicWorkerCreationEvents();\n return workerNodeKey;\n }\n /**\n * Method hooked up after a worker node has been newly created.\n * Can be overridden.\n *\n * @param workerNodeKey - The newly created worker node key.\n */\n afterWorkerNodeSetup(workerNodeKey) {\n // Listen to worker messages.\n this.registerWorkerMessageListener(workerNodeKey, this.workerListener());\n // Send the startup message to worker.\n this.sendStartupMessageToWorker(workerNodeKey);\n // Send the statistics message to worker.\n this.sendStatisticsMessageToWorker(workerNodeKey);\n if (this.opts.enableTasksQueue === true) {\n if (this.opts.tasksQueueOptions?.taskStealing === true) {\n this.workerNodes[workerNodeKey].onEmptyQueue =\n this.taskStealingOnEmptyQueue.bind(this);\n }\n if (this.opts.tasksQueueOptions?.tasksStealingOnBackPressure === true) {\n this.workerNodes[workerNodeKey].onBackPressure =\n this.tasksStealingOnBackPressure.bind(this);\n }\n }\n }\n /**\n * Sends the statistics message to worker given its worker node key.\n *\n * @param workerNodeKey - The worker node key.\n */\n sendStatisticsMessageToWorker(workerNodeKey) {\n this.sendToWorker(workerNodeKey, {\n statistics: {\n runTime: this.workerChoiceStrategyContext.getTaskStatisticsRequirements()\n .runTime.aggregate,\n elu: this.workerChoiceStrategyContext.getTaskStatisticsRequirements()\n .elu.aggregate\n }\n });\n }\n redistributeQueuedTasks(workerNodeKey) {\n while (this.tasksQueueSize(workerNodeKey) > 0) {\n const destinationWorkerNodeKey = this.workerNodes.reduce((minWorkerNodeKey, workerNode, workerNodeKey, workerNodes) => {\n return workerNode.info.ready &&\n workerNode.usage.tasks.queued <\n workerNodes[minWorkerNodeKey].usage.tasks.queued\n ? workerNodeKey\n : minWorkerNodeKey;\n }, 0);\n const task = this.dequeueTask(workerNodeKey);\n if (this.shallExecuteTask(destinationWorkerNodeKey)) {\n this.executeTask(destinationWorkerNodeKey, task);\n }\n else {\n this.enqueueTask(destinationWorkerNodeKey, task);\n }\n }\n }\n updateTaskStolenStatisticsWorkerUsage(workerNodeKey, taskName) {\n const workerNode = this.workerNodes[workerNodeKey];\n if (workerNode?.usage != null) {\n ++workerNode.usage.tasks.stolen;\n }\n if (this.shallUpdateTaskFunctionWorkerUsage(workerNodeKey) &&\n workerNode.getTaskFunctionWorkerUsage(taskName) != null) {\n const taskFunctionWorkerUsage = workerNode.getTaskFunctionWorkerUsage(taskName);\n ++taskFunctionWorkerUsage.tasks.stolen;\n }\n }\n taskStealingOnEmptyQueue(workerId) {\n const destinationWorkerNodeKey = this.getWorkerNodeKeyByWorkerId(workerId);\n const workerNodes = this.workerNodes\n .slice()\n .sort((workerNodeA, workerNodeB) => workerNodeB.usage.tasks.queued - workerNodeA.usage.tasks.queued);\n const sourceWorkerNode = workerNodes.find(workerNode => workerNode.info.ready &&\n workerNode.info.id !== workerId &&\n workerNode.usage.tasks.queued > 0);\n if (sourceWorkerNode != null) {\n const task = sourceWorkerNode.popTask();\n if (this.shallExecuteTask(destinationWorkerNodeKey)) {\n this.executeTask(destinationWorkerNodeKey, task);\n }\n else {\n this.enqueueTask(destinationWorkerNodeKey, task);\n }\n this.updateTaskStolenStatisticsWorkerUsage(destinationWorkerNodeKey, task.name);\n }\n }\n tasksStealingOnBackPressure(workerId) {\n const sizeOffset = 1;\n if (this.opts.tasksQueueOptions?.size <= sizeOffset) {\n return;\n }\n const sourceWorkerNode = this.workerNodes[this.getWorkerNodeKeyByWorkerId(workerId)];\n const workerNodes = this.workerNodes\n .slice()\n .sort((workerNodeA, workerNodeB) => workerNodeA.usage.tasks.queued - workerNodeB.usage.tasks.queued);\n for (const [workerNodeKey, workerNode] of workerNodes.entries()) {\n if (sourceWorkerNode.usage.tasks.queued > 0 &&\n workerNode.info.ready &&\n workerNode.info.id !== workerId &&\n workerNode.usage.tasks.queued <\n this.opts.tasksQueueOptions?.size - sizeOffset) {\n const task = sourceWorkerNode.popTask();\n if (this.shallExecuteTask(workerNodeKey)) {\n this.executeTask(workerNodeKey, task);\n }\n else {\n this.enqueueTask(workerNodeKey, task);\n }\n this.updateTaskStolenStatisticsWorkerUsage(workerNodeKey, task.name);\n }\n }\n }\n /**\n * This method is the listener registered for each worker message.\n *\n * @returns The listener function to execute when a message is received from a worker.\n */\n workerListener() {\n return message => {\n this.checkMessageWorkerId(message);\n if (message.ready != null && message.taskFunctionNames != null) {\n // Worker ready response received from worker\n this.handleWorkerReadyResponse(message);\n }\n else if (message.taskId != null) {\n // Task execution response received from worker\n this.handleTaskExecutionResponse(message);\n }\n else if (message.taskFunctionNames != null) {\n // Task function names message received from worker\n this.getWorkerInfo(this.getWorkerNodeKeyByWorkerId(message.workerId)).taskFunctionNames = message.taskFunctionNames;\n }\n };\n }\n handleWorkerReadyResponse(message) {\n if (message.ready === false) {\n throw new Error(`Worker ${message.workerId} failed to initialize`);\n }\n const workerInfo = this.getWorkerInfo(this.getWorkerNodeKeyByWorkerId(message.workerId));\n workerInfo.ready = message.ready;\n workerInfo.taskFunctionNames = message.taskFunctionNames;\n if (this.ready) {\n this.emitter?.emit(PoolEvents.ready, this.info);\n }\n }\n handleTaskExecutionResponse(message) {\n const { taskId, workerError, data } = message;\n const promiseResponse = this.promiseResponseMap.get(taskId);\n if (promiseResponse != null) {\n if (workerError != null) {\n this.emitter?.emit(PoolEvents.taskError, workerError);\n promiseResponse.reject(workerError.message);\n }\n else {\n promiseResponse.resolve(data);\n }\n const workerNodeKey = promiseResponse.workerNodeKey;\n this.afterTaskExecutionHook(workerNodeKey, message);\n this.workerChoiceStrategyContext.update(workerNodeKey);\n this.promiseResponseMap.delete(taskId);\n if (this.opts.enableTasksQueue === true &&\n this.tasksQueueSize(workerNodeKey) > 0 &&\n this.workerNodes[workerNodeKey].usage.tasks.executing <\n this.opts.tasksQueueOptions?.concurrency) {\n this.executeTask(workerNodeKey, this.dequeueTask(workerNodeKey));\n }\n }\n }\n checkAndEmitTaskExecutionEvents() {\n if (this.busy) {\n this.emitter?.emit(PoolEvents.busy, this.info);\n }\n }\n checkAndEmitTaskQueuingEvents() {\n if (this.hasBackPressure()) {\n this.emitter?.emit(PoolEvents.backPressure, this.info);\n }\n }\n checkAndEmitDynamicWorkerCreationEvents() {\n if (this.type === PoolTypes.dynamic) {\n if (this.full) {\n this.emitter?.emit(PoolEvents.full, this.info);\n }\n }\n }\n /**\n * Gets the worker information given its worker node key.\n *\n * @param workerNodeKey - The worker node key.\n * @returns The worker information.\n */\n getWorkerInfo(workerNodeKey) {\n return this.workerNodes[workerNodeKey].info;\n }\n /**\n * Adds the given worker in the pool worker nodes.\n *\n * @param worker - The worker.\n * @returns The added worker node key.\n * @throws {@link https://nodejs.org/api/errors.html#class-error} If the added worker node is not found.\n */\n addWorkerNode(worker) {\n const workerNode = new WorkerNode(worker, this.opts.tasksQueueOptions?.size ?? Math.pow(this.maxSize, 2));\n // Flag the worker node as ready at pool startup.\n if (this.starting) {\n workerNode.info.ready = true;\n }\n this.workerNodes.push(workerNode);\n const workerNodeKey = this.getWorkerNodeKeyByWorker(worker);\n if (workerNodeKey === -1) {\n throw new Error('Worker added not found in worker nodes');\n }\n return workerNodeKey;\n }\n /**\n * Removes the given worker from the pool worker nodes.\n *\n * @param worker - The worker.\n */\n removeWorkerNode(worker) {\n const workerNodeKey = this.getWorkerNodeKeyByWorker(worker);\n if (workerNodeKey !== -1) {\n this.workerNodes.splice(workerNodeKey, 1);\n this.workerChoiceStrategyContext.remove(workerNodeKey);\n }\n }\n /** @inheritDoc */\n hasWorkerNodeBackPressure(workerNodeKey) {\n return (this.opts.enableTasksQueue === true &&\n this.workerNodes[workerNodeKey].hasBackPressure());\n }\n hasBackPressure() {\n return (this.opts.enableTasksQueue === true &&\n this.workerNodes.findIndex(workerNode => !workerNode.hasBackPressure()) === -1);\n }\n /**\n * Executes the given task on the worker given its worker node key.\n *\n * @param workerNodeKey - The worker node key.\n * @param task - The task to execute.\n */\n executeTask(workerNodeKey, task) {\n this.beforeTaskExecutionHook(workerNodeKey, task);\n this.sendToWorker(workerNodeKey, task, task.transferList);\n this.checkAndEmitTaskExecutionEvents();\n }\n enqueueTask(workerNodeKey, task) {\n const tasksQueueSize = this.workerNodes[workerNodeKey].enqueueTask(task);\n this.checkAndEmitTaskQueuingEvents();\n return tasksQueueSize;\n }\n dequeueTask(workerNodeKey) {\n return this.workerNodes[workerNodeKey].dequeueTask();\n }\n tasksQueueSize(workerNodeKey) {\n return this.workerNodes[workerNodeKey].tasksQueueSize();\n }\n flushTasksQueue(workerNodeKey) {\n while (this.tasksQueueSize(workerNodeKey) > 0) {\n this.executeTask(workerNodeKey, this.dequeueTask(workerNodeKey));\n }\n this.workerNodes[workerNodeKey].clearTasksQueue();\n }\n flushTasksQueues() {\n for (const [workerNodeKey] of this.workerNodes.entries()) {\n this.flushTasksQueue(workerNodeKey);\n }\n }\n}\n//# sourceMappingURL=abstract-pool.js.map","export const version = '2.7.3';\n//# sourceMappingURL=version.js.map","import cluster, {} from 'node:cluster';\nimport { AbstractPool } from '../abstract-pool';\nimport { PoolTypes } from '../pool';\nimport { WorkerTypes } from '../worker';\n/**\n * A cluster pool with a fixed number of workers.\n *\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n * @typeParam Response - Type of execution response. This can only be structured-cloneable data.\n * @author [Christopher Quadflieg](https://github.com/Shinigami92)\n * @since 2.0.0\n */\nexport class FixedClusterPool extends AbstractPool {\n opts;\n /**\n * Constructs a new poolifier fixed cluster pool.\n *\n * @param numberOfWorkers - Number of workers for this pool.\n * @param filePath - Path to an implementation of a `ClusterWorker` file, which can be relative or absolute.\n * @param opts - Options for this fixed cluster pool.\n */\n constructor(numberOfWorkers, filePath, opts = {}) {\n super(numberOfWorkers, filePath, opts);\n this.opts = opts;\n }\n /** @inheritDoc */\n setupHook() {\n cluster.setupPrimary({ ...this.opts.settings, exec: this.filePath });\n }\n /** @inheritDoc */\n isMain() {\n return cluster.isPrimary;\n }\n /** @inheritDoc */\n async destroyWorkerNode(workerNodeKey) {\n this.flushTasksQueue(workerNodeKey);\n // FIXME: wait for tasks to be finished\n const workerNode = this.workerNodes[workerNodeKey];\n const worker = workerNode.worker;\n const waitWorkerExit = new Promise(resolve => {\n worker.once('exit', () => {\n resolve();\n });\n });\n worker.once('disconnect', () => {\n worker.kill();\n });\n await this.sendKillMessageToWorker(workerNodeKey);\n worker.disconnect();\n await waitWorkerExit;\n }\n /** @inheritDoc */\n sendToWorker(workerNodeKey, message) {\n this.workerNodes[workerNodeKey].worker.send({\n ...message,\n workerId: this.workerNodes[workerNodeKey].info.id\n });\n }\n /** @inheritDoc */\n sendStartupMessageToWorker(workerNodeKey) {\n this.sendToWorker(workerNodeKey, {\n ready: false\n });\n }\n /** @inheritDoc */\n registerWorkerMessageListener(workerNodeKey, listener) {\n this.workerNodes[workerNodeKey].worker.on('message', listener);\n }\n /** @inheritDoc */\n registerOnceWorkerMessageListener(workerNodeKey, listener) {\n this.workerNodes[workerNodeKey].worker.once('message', listener);\n }\n /** @inheritDoc */\n deregisterWorkerMessageListener(workerNodeKey, listener) {\n this.workerNodes[workerNodeKey].worker.off('message', listener);\n }\n /** @inheritDoc */\n createWorker() {\n return cluster.fork(this.opts.env);\n }\n /** @inheritDoc */\n get type() {\n return PoolTypes.fixed;\n }\n /** @inheritDoc */\n get worker() {\n return WorkerTypes.cluster;\n }\n /** @inheritDoc */\n get busy() {\n return this.internalBusy();\n }\n}\n//# sourceMappingURL=fixed.js.map","import { PoolTypes } from '../pool';\nimport { checkDynamicPoolSize } from '../utils';\nimport { FixedClusterPool } from './fixed';\n/**\n * A cluster pool with a dynamic number of workers, but a guaranteed minimum number of workers.\n *\n * This cluster pool creates new workers when the others are busy, up to the maximum number of workers.\n * When the maximum number of workers is reached and workers are busy, an event is emitted. If you want to listen to this event, use the pool's `emitter`.\n *\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n * @typeParam Response - Type of execution response. This can only be structured-cloneable data.\n * @author [Christopher Quadflieg](https://github.com/Shinigami92)\n * @since 2.0.0\n */\nexport class DynamicClusterPool extends FixedClusterPool {\n max;\n /**\n * Constructs a new poolifier dynamic cluster pool.\n *\n * @param min - Minimum number of workers which are always active.\n * @param max - Maximum number of workers that can be created by this pool.\n * @param filePath - Path to an implementation of a `ClusterWorker` file, which can be relative or absolute.\n * @param opts - Options for this dynamic cluster pool.\n */\n constructor(min, max, filePath, opts = {}) {\n super(min, filePath, opts);\n this.max = max;\n checkDynamicPoolSize(this.numberOfWorkers, this.max);\n }\n /** @inheritDoc */\n get type() {\n return PoolTypes.dynamic;\n }\n /** @inheritDoc */\n get busy() {\n return this.full && this.internalBusy();\n }\n}\n//# sourceMappingURL=dynamic.js.map","import { SHARE_ENV, Worker, isMainThread } from 'node:worker_threads';\nimport { AbstractPool } from '../abstract-pool';\nimport { PoolTypes } from '../pool';\nimport { WorkerTypes } from '../worker';\n/**\n * A thread pool with a fixed number of threads.\n *\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n * @typeParam Response - Type of execution response. This can only be structured-cloneable data.\n * @author [Alessandro Pio Ardizio](https://github.com/pioardi)\n * @since 0.0.1\n */\nexport class FixedThreadPool extends AbstractPool {\n opts;\n /**\n * Constructs a new poolifier fixed thread pool.\n *\n * @param numberOfThreads - Number of threads for this pool.\n * @param filePath - Path to an implementation of a `ThreadWorker` file, which can be relative or absolute.\n * @param opts - Options for this fixed thread pool.\n */\n constructor(numberOfThreads, filePath, opts = {}) {\n super(numberOfThreads, filePath, opts);\n this.opts = opts;\n }\n /** @inheritDoc */\n isMain() {\n return isMainThread;\n }\n /** @inheritDoc */\n async destroyWorkerNode(workerNodeKey) {\n this.flushTasksQueue(workerNodeKey);\n // FIXME: wait for tasks to be finished\n const workerNode = this.workerNodes[workerNodeKey];\n const worker = workerNode.worker;\n const waitWorkerExit = new Promise(resolve => {\n worker.once('exit', () => {\n resolve();\n });\n });\n await this.sendKillMessageToWorker(workerNodeKey);\n workerNode.closeChannel();\n await worker.terminate();\n await waitWorkerExit;\n }\n /** @inheritDoc */\n sendToWorker(workerNodeKey, message, transferList) {\n this.workerNodes[workerNodeKey].messageChannel.port1.postMessage({ ...message, workerId: this.workerNodes[workerNodeKey].info.id }, transferList);\n }\n /** @inheritDoc */\n sendStartupMessageToWorker(workerNodeKey) {\n const workerNode = this.workerNodes[workerNodeKey];\n const port2 = workerNode.messageChannel\n .port2;\n workerNode.worker.postMessage({\n ready: false,\n workerId: workerNode.info.id,\n port: port2\n }, [port2]);\n }\n /** @inheritDoc */\n registerWorkerMessageListener(workerNodeKey, listener) {\n this.workerNodes[workerNodeKey].messageChannel.port1.on('message', listener);\n }\n /** @inheritDoc */\n registerOnceWorkerMessageListener(workerNodeKey, listener) {\n this.workerNodes[workerNodeKey].messageChannel.port1.once('message', listener);\n }\n /** @inheritDoc */\n deregisterWorkerMessageListener(workerNodeKey, listener) {\n this.workerNodes[workerNodeKey].messageChannel.port1.off('message', listener);\n }\n /** @inheritDoc */\n createWorker() {\n return new Worker(this.filePath, {\n env: SHARE_ENV,\n ...this.opts.workerOptions\n });\n }\n /** @inheritDoc */\n get type() {\n return PoolTypes.fixed;\n }\n /** @inheritDoc */\n get worker() {\n return WorkerTypes.thread;\n }\n /** @inheritDoc */\n get busy() {\n return this.internalBusy();\n }\n}\n//# sourceMappingURL=fixed.js.map","import { PoolTypes } from '../pool';\nimport { checkDynamicPoolSize } from '../utils';\nimport { FixedThreadPool } from './fixed';\n/**\n * A thread pool with a dynamic number of threads, but a guaranteed minimum number of threads.\n *\n * This thread pool creates new threads when the others are busy, up to the maximum number of threads.\n * When the maximum number of threads is reached and workers are busy, an event is emitted. If you want to listen to this event, use the pool's `emitter`.\n *\n * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.\n * @typeParam Response - Type of execution response. This can only be structured-cloneable data.\n * @author [Alessandro Pio Ardizio](https://github.com/pioardi)\n * @since 0.0.1\n */\nexport class DynamicThreadPool extends FixedThreadPool {\n max;\n /**\n * Constructs a new poolifier dynamic thread pool.\n *\n * @param min - Minimum number of threads which are always active.\n * @param max - Maximum number of threads that can be created by this pool.\n * @param filePath - Path to an implementation of a `ThreadWorker` file, which can be relative or absolute.\n * @param opts - Options for this dynamic thread pool.\n */\n constructor(min, max, filePath, opts = {}) {\n super(min, filePath, opts);\n this.max = max;\n checkDynamicPoolSize(this.numberOfWorkers, this.max);\n }\n /** @inheritDoc */\n get type() {\n return PoolTypes.dynamic;\n }\n /** @inheritDoc */\n get busy() {\n return this.full && this.internalBusy();\n }\n}\n//# sourceMappingURL=dynamic.js.map","import { isPlainObject } from '../utils';\nimport { KillBehaviors } from './worker-options';\nexport const checkValidWorkerOptions = (opts) => {\n if (opts != null && !isPlainObject(opts)) {\n throw new TypeError('opts worker options parameter is not a plain object');\n }\n if (opts?.killBehavior != null &&\n !Object.values(KillBehaviors).includes(opts.killBehavior)) {\n throw new TypeError(`killBehavior option '${opts.killBehavior}' is not valid`);\n }\n if (opts?.maxInactiveTime != null &&\n !Number.isSafeInteger(opts.maxInactiveTime)) {\n throw new TypeError('maxInactiveTime option is not an integer');\n }\n if (opts?.maxInactiveTime != null && opts.maxInactiveTime < 5) {\n throw new TypeError('maxInactiveTime option is not a positive integer greater or equal than 5');\n }\n if (opts?.killHandler != null && typeof opts.killHandler !== 'function') {\n throw new TypeError('killHandler option is not a function');\n }\n if (opts?.async != null) {\n throw new Error('async option is deprecated');\n }\n};\nexport const checkValidTaskFunctionEntry = (name, fn) => {\n if (typeof name !== 'string') {\n throw new TypeError('A taskFunctions parameter object key is not a string');\n }\n if (typeof name === 'string' && name.trim().length === 0) {\n throw new TypeError('A taskFunctions parameter object key is an empty string');\n }\n if (typeof fn !== 'function') {\n throw new TypeError('A taskFunctions parameter object value is not a function');\n }\n};\nexport const checkTaskFunctionName = (name) => {\n if (typeof name !== 'string') {\n throw new TypeError('name parameter is not a string');\n }\n if (typeof name === 'string' && name.trim().length === 0) {\n throw new TypeError('name parameter is an empty string');\n }\n};\n//# sourceMappingURL=utils.js.map","import { AsyncResource } from 'node:async_hooks';\nimport { performance } from 'node:perf_hooks';\nimport { DEFAULT_TASK_NAME, EMPTY_FUNCTION, isAsyncFunction, isPlainObject } from '../utils';\nimport { KillBehaviors } from './worker-options';\nimport { checkTaskFunctionName, checkValidTaskFunctionEntry, checkValidWorkerOptions } from './utils';\nconst DEFAULT_MAX_INACTIVE_TIME = 60000;\nconst DEFAULT_WORKER_OPTIONS = {\n /**\n * The kill behavior option on this worker or its default value.\n */\n killBehavior: KillBehaviors.SOFT,\n /**\n * The maximum time to keep this worker active while idle.\n * The pool automatically checks and terminates this worker when the time expires.\n */\n maxInactiveTime: DEFAULT_MAX_INACTIVE_TIME,\n /**\n * The function to call when the worker is killed.\n */\n killHandler: EMPTY_FUNCTION\n};\n/**\n * Base class that implements some shared logic for all poolifier workers.\n *\n * @typeParam MainWorker - Type of main worker.\n * @typeParam Data - Type of data this worker receives from pool's execution. This can only be structured-cloneable data.\n * @typeParam Response - Type of response the worker sends back to the main worker. This can only be structured-cloneable data.\n */\nexport class AbstractWorker extends AsyncResource {\n isMain;\n mainWorker;\n opts;\n /**\n * Task function(s) processed by the worker when the pool's `execution` function is invoked.\n */\n taskFunctions;\n /**\n * Timestamp of the last task processed by this worker.\n */\n lastTaskTimestamp;\n /**\n * Performance statistics computation requirements.\n */\n statistics;\n /**\n * Handler id of the `activeInterval` worker activity check.\n */\n activeInterval;\n /**\n * Constructs a new poolifier worker.\n *\n * @param type - The type of async event.\n * @param isMain - Whether this is the main worker or not.\n * @param mainWorker - Reference to main worker.\n * @param taskFunctions - Task function(s) processed by the worker when the pool's `execution` function is invoked. The first function is the default function.\n * @param opts - Options for the worker.\n */\n constructor(type, isMain, mainWorker, taskFunctions, opts = DEFAULT_WORKER_OPTIONS) {\n super(type);\n this.isMain = isMain;\n this.mainWorker = mainWorker;\n this.opts = opts;\n if (this.isMain == null) {\n throw new Error('isMain parameter is mandatory');\n }\n this.checkTaskFunctions(taskFunctions);\n this.checkWorkerOptions(this.opts);\n if (!this.isMain) {\n // Should be once() but Node.js on windows has a bug that prevents it from working\n this.getMainWorker().on('message', this.handleReadyMessage.bind(this));\n }\n }\n checkWorkerOptions(opts) {\n checkValidWorkerOptions(opts);\n this.opts = { ...DEFAULT_WORKER_OPTIONS, ...opts };\n }\n /**\n * Checks if the `taskFunctions` parameter is passed to the constructor and valid.\n *\n * @param taskFunctions - The task function(s) parameter that should be checked.\n */\n checkTaskFunctions(taskFunctions) {\n if (taskFunctions == null) {\n throw new Error('taskFunctions parameter is mandatory');\n }\n this.taskFunctions = new Map();\n if (typeof taskFunctions === 'function') {\n const boundFn = taskFunctions.bind(this);\n this.taskFunctions.set(DEFAULT_TASK_NAME, boundFn);\n this.taskFunctions.set(typeof taskFunctions.name === 'string' &&\n taskFunctions.name.trim().length > 0\n ? taskFunctions.name\n : 'fn1', boundFn);\n }\n else if (isPlainObject(taskFunctions)) {\n let firstEntry = true;\n for (const [name, fn] of Object.entries(taskFunctions)) {\n checkValidTaskFunctionEntry(name, fn);\n const boundFn = fn.bind(this);\n if (firstEntry) {\n this.taskFunctions.set(DEFAULT_TASK_NAME, boundFn);\n firstEntry = false;\n }\n this.taskFunctions.set(name, boundFn);\n }\n if (firstEntry) {\n throw new Error('taskFunctions parameter object is empty');\n }\n }\n else {\n throw new TypeError('taskFunctions parameter is not a function or a plain object');\n }\n }\n /**\n * Checks if the worker has a task function with the given name.\n *\n * @param name - The name of the task function to check.\n * @returns Whether the worker has a task function with the given name or not.\n */\n hasTaskFunction(name) {\n try {\n checkTaskFunctionName(name);\n }\n catch (error) {\n return { status: false, error: error };\n }\n return { status: this.taskFunctions.has(name) };\n }\n /**\n * Adds a task function to the worker.\n * If a task function with the same name already exists, it is replaced.\n *\n * @param name - The name of the task function to add.\n * @param fn - The task function to add.\n * @returns Whether the task function was added or not.\n */\n addTaskFunction(name, fn) {\n try {\n checkTaskFunctionName(name);\n if (name === DEFAULT_TASK_NAME) {\n throw new Error('Cannot add a task function with the default reserved name');\n }\n if (typeof fn !== 'function') {\n throw new TypeError('fn parameter is not a function');\n }\n const boundFn = fn.bind(this);\n if (this.taskFunctions.get(name) ===\n this.taskFunctions.get(DEFAULT_TASK_NAME)) {\n this.taskFunctions.set(DEFAULT_TASK_NAME, boundFn);\n }\n this.taskFunctions.set(name, boundFn);\n this.sendTaskFunctionNamesToMainWorker();\n return { status: true };\n }\n catch (error) {\n return { status: false, error: error };\n }\n }\n /**\n * Removes a task function from the worker.\n *\n * @param name - The name of the task function to remove.\n * @returns Whether the task function existed and was removed or not.\n */\n removeTaskFunction(name) {\n try {\n checkTaskFunctionName(name);\n if (name === DEFAULT_TASK_NAME) {\n throw new Error('Cannot remove the task function with the default reserved name');\n }\n if (this.taskFunctions.get(name) ===\n this.taskFunctions.get(DEFAULT_TASK_NAME)) {\n throw new Error('Cannot remove the task function used as the default task function');\n }\n const deleteStatus = this.taskFunctions.delete(name);\n this.sendTaskFunctionNamesToMainWorker();\n return { status: deleteStatus };\n }\n catch (error) {\n return { status: false, error: error };\n }\n }\n /**\n * Lists the names of the worker's task functions.\n *\n * @returns The names of the worker's task functions.\n */\n listTaskFunctionNames() {\n const names = [...this.taskFunctions.keys()];\n let defaultTaskFunctionName = DEFAULT_TASK_NAME;\n for (const [name, fn] of this.taskFunctions) {\n if (name !== DEFAULT_TASK_NAME &&\n fn === this.taskFunctions.get(DEFAULT_TASK_NAME)) {\n defaultTaskFunctionName = name;\n break;\n }\n }\n return [\n names[names.indexOf(DEFAULT_TASK_NAME)],\n defaultTaskFunctionName,\n ...names.filter(name => name !== DEFAULT_TASK_NAME && name !== defaultTaskFunctionName)\n ];\n }\n /**\n * Sets the default task function to use in the worker.\n *\n * @param name - The name of the task function to use as default task function.\n * @returns Whether the default task function was set or not.\n */\n setDefaultTaskFunction(name) {\n try {\n checkTaskFunctionName(name);\n if (name === DEFAULT_TASK_NAME) {\n throw new Error('Cannot set the default task function reserved name as the default task function');\n }\n if (!this.taskFunctions.has(name)) {\n throw new Error('Cannot set the default task function to a non-existing task function');\n }\n this.taskFunctions.set(DEFAULT_TASK_NAME, this.taskFunctions.get(name));\n this.sendTaskFunctionNamesToMainWorker();\n return { status: true };\n }\n catch (error) {\n return { status: false, error: error };\n }\n }\n /**\n * Worker message listener.\n *\n * @param message - The received message.\n */\n messageListener(message) {\n this.checkMessageWorkerId(message);\n if (message.statistics != null) {\n // Statistics message received\n this.statistics = message.statistics;\n }\n else if (message.checkActive != null) {\n // Check active message received\n message.checkActive ? this.startCheckActive() : this.stopCheckActive();\n }\n else if (message.taskFunctionOperation != null) {\n // Task function operation message received\n this.handleTaskFunctionOperationMessage(message);\n }\n else if (message.taskId != null && message.data != null) {\n // Task message received\n this.run(message);\n }\n else if (message.kill === true) {\n // Kill message received\n this.handleKillMessage(message);\n }\n }\n handleTaskFunctionOperationMessage(message) {\n const { taskFunctionOperation, taskFunctionName, taskFunction } = message;\n let response;\n switch (taskFunctionOperation) {\n case 'add':\n response = this.addTaskFunction(taskFunctionName, \n // eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func\n new Function(`return ${taskFunction}`)());\n break;\n case 'remove':\n response = this.removeTaskFunction(taskFunctionName);\n break;\n case 'default':\n response = this.setDefaultTaskFunction(taskFunctionName);\n break;\n default:\n response = { status: false, error: new Error('Unknown task operation') };\n break;\n }\n this.sendToMainWorker({\n taskFunctionOperation,\n taskFunctionOperationStatus: response.status,\n taskFunctionName,\n ...(!response.status &&\n response?.error != null && {\n workerError: {\n name: taskFunctionName,\n message: this.handleError(response.error)\n }\n })\n });\n }\n /**\n * Handles a kill message sent by the main worker.\n *\n * @param message - The kill message.\n */\n handleKillMessage(message) {\n this.stopCheckActive();\n if (isAsyncFunction(this.opts.killHandler)) {\n (this.opts.killHandler?.())\n .then(() => {\n this.sendToMainWorker({ kill: 'success' });\n return null;\n })\n .catch(() => {\n this.sendToMainWorker({ kill: 'failure' });\n })\n .finally(() => {\n this.emitDestroy();\n })\n .catch(EMPTY_FUNCTION);\n }\n else {\n try {\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n this.opts.killHandler?.();\n this.sendToMainWorker({ kill: 'success' });\n }\n catch {\n this.sendToMainWorker({ kill: 'failure' });\n }\n finally {\n this.emitDestroy();\n }\n }\n }\n /**\n * Check if the message worker id is set and matches the worker id.\n *\n * @param message - The message to check.\n * @throws {@link https://nodejs.org/api/errors.html#class-error} If the message worker id is not set or does not match the worker id.\n */\n checkMessageWorkerId(message) {\n if (message.workerId == null) {\n throw new Error('Message worker id is not set');\n }\n else if (message.workerId != null && message.workerId !== this.id) {\n throw new Error(`Message worker id ${message.workerId} does not match the worker id ${this.id}`);\n }\n }\n /**\n * Starts the worker check active interval.\n */\n startCheckActive() {\n this.lastTaskTimestamp = performance.now();\n this.activeInterval = setInterval(this.checkActive.bind(this), (this.opts.maxInactiveTime ?? DEFAULT_MAX_INACTIVE_TIME) / 2);\n }\n /**\n * Stops the worker check active interval.\n */\n stopCheckActive() {\n if (this.activeInterval != null) {\n clearInterval(this.activeInterval);\n delete this.activeInterval;\n }\n }\n /**\n * Checks if the worker should be terminated, because its living too long.\n */\n checkActive() {\n if (performance.now() - this.lastTaskTimestamp >\n (this.opts.maxInactiveTime ?? DEFAULT_MAX_INACTIVE_TIME)) {\n this.sendToMainWorker({ kill: this.opts.killBehavior });\n }\n }\n /**\n * Returns the main worker.\n *\n * @returns Reference to the main worker.\n * @throws {@link https://nodejs.org/api/errors.html#class-error} If the main worker is not set.\n */\n getMainWorker() {\n if (this.mainWorker == null) {\n throw new Error('Main worker not set');\n }\n return this.mainWorker;\n }\n /**\n * Sends task function names to the main worker.\n */\n sendTaskFunctionNamesToMainWorker() {\n this.sendToMainWorker({\n taskFunctionNames: this.listTaskFunctionNames()\n });\n }\n /**\n * Handles an error and convert it to a string so it can be sent back to the main worker.\n *\n * @param error - The error raised by the worker.\n * @returns The error message.\n */\n handleError(error) {\n return error instanceof Error ? error.message : error;\n }\n /**\n * Runs the given task.\n *\n * @param task - The task to execute.\n */\n run(task) {\n const { name, taskId, data } = task;\n const fn = this.taskFunctions.get(name ?? DEFAULT_TASK_NAME);\n if (fn == null) {\n this.sendToMainWorker({\n workerError: {\n name: name,\n message: `Task function '${name}' not found`,\n data\n },\n taskId\n });\n return;\n }\n if (isAsyncFunction(fn)) {\n this.runInAsyncScope(this.runAsync.bind(this), this, fn, task);\n }\n else {\n this.runInAsyncScope(this.runSync.bind(this), this, fn, task);\n }\n }\n /**\n * Runs the given task function synchronously.\n *\n * @param fn - Task function that will be executed.\n * @param task - Input data for the task function.\n */\n runSync(fn, task) {\n const { name, taskId, data } = task;\n try {\n let taskPerformance = this.beginTaskPerformance(name);\n const res = fn(data);\n taskPerformance = this.endTaskPerformance(taskPerformance);\n this.sendToMainWorker({\n data: res,\n taskPerformance,\n taskId\n });\n }\n catch (error) {\n this.sendToMainWorker({\n workerError: {\n name: name,\n message: this.handleError(error),\n data\n },\n taskId\n });\n }\n finally {\n this.updateLastTaskTimestamp();\n }\n }\n /**\n * Runs the given task function asynchronously.\n *\n * @param fn - Task function that will be executed.\n * @param task - Input data for the task function.\n */\n runAsync(fn, task) {\n const { name, taskId, data } = task;\n let taskPerformance = this.beginTaskPerformance(name);\n fn(data)\n .then(res => {\n taskPerformance = this.endTaskPerformance(taskPerformance);\n this.sendToMainWorker({\n data: res,\n taskPerformance,\n taskId\n });\n return undefined;\n })\n .catch(error => {\n this.sendToMainWorker({\n workerError: {\n name: name,\n message: this.handleError(error),\n data\n },\n taskId\n });\n })\n .finally(() => {\n this.updateLastTaskTimestamp();\n })\n .catch(EMPTY_FUNCTION);\n }\n beginTaskPerformance(name) {\n this.checkStatistics();\n return {\n name: name ?? DEFAULT_TASK_NAME,\n timestamp: performance.now(),\n ...(this.statistics.elu && { elu: performance.eventLoopUtilization() })\n };\n }\n endTaskPerformance(taskPerformance) {\n this.checkStatistics();\n return {\n ...taskPerformance,\n ...(this.statistics.runTime && {\n runTime: performance.now() - taskPerformance.timestamp\n }),\n ...(this.statistics.elu && {\n elu: performance.eventLoopUtilization(taskPerformance.elu)\n })\n };\n }\n checkStatistics() {\n if (this.statistics == null) {\n throw new Error('Performance statistics computation requirements not set');\n }\n }\n updateLastTaskTimestamp() {\n if (this.activeInterval != null) {\n this.lastTaskTimestamp = performance.now();\n }\n }\n}\n//# sourceMappingURL=abstract-worker.js.map","import cluster, {} from 'node:cluster';\nimport { AbstractWorker } from './abstract-worker';\n/**\n * A cluster worker used by a poolifier `ClusterPool`.\n *\n * When this worker is inactive for more than the given `maxInactiveTime`,\n * it will send a termination request to its main worker.\n *\n * If you use a `DynamicClusterPool` the extra workers that were created will be terminated,\n * but the minimum number of workers will be guaranteed.\n *\n * @typeParam Data - Type of data this worker receives from pool's execution. This can only be structured-cloneable data.\n * @typeParam Response - Type of response the worker sends back to the main worker. This can only be structured-cloneable data.\n * @author [Christopher Quadflieg](https://github.com/Shinigami92)\n * @since 2.0.0\n */\nexport class ClusterWorker extends AbstractWorker {\n /**\n * Constructs a new poolifier cluster worker.\n *\n * @param taskFunctions - Task function(s) processed by the worker when the pool's `execution` function is invoked.\n * @param opts - Options for the worker.\n */\n constructor(taskFunctions, opts = {}) {\n super('poolifier:cluster-worker', cluster.isPrimary, cluster.worker, taskFunctions, opts);\n }\n /** @inheritDoc */\n handleReadyMessage(message) {\n if (message.workerId === this.id && message.ready === false) {\n try {\n this.getMainWorker().on('message', this.messageListener.bind(this));\n this.sendToMainWorker({\n ready: true,\n taskFunctionNames: this.listTaskFunctionNames()\n });\n }\n catch {\n this.sendToMainWorker({\n ready: false,\n taskFunctionNames: this.listTaskFunctionNames()\n });\n }\n }\n }\n /** @inheritDoc */\n get id() {\n return this.getMainWorker().id;\n }\n /** @inheritDoc */\n sendToMainWorker(message) {\n this.getMainWorker().send({ ...message, workerId: this.id });\n }\n}\n//# sourceMappingURL=cluster-worker.js.map","import { isMainThread, parentPort, threadId } from 'node:worker_threads';\nimport { AbstractWorker } from './abstract-worker';\n/**\n * A thread worker used by a poolifier `ThreadPool`.\n *\n * When this worker is inactive for more than the given `maxInactiveTime`,\n * it will send a termination request to its main thread.\n *\n * If you use a `DynamicThreadPool` the extra workers that were created will be terminated,\n * but the minimum number of workers will be guaranteed.\n *\n * @typeParam Data - Type of data this worker receives from pool's execution. This can only be structured-cloneable data.\n * @typeParam Response - Type of response the worker sends back to the main thread. This can only be structured-cloneable data.\n * @author [Alessandro Pio Ardizio](https://github.com/pioardi)\n * @since 0.0.1\n */\nexport class ThreadWorker extends AbstractWorker {\n /**\n * Message port used to communicate with the main worker.\n */\n port;\n /**\n * Constructs a new poolifier thread worker.\n *\n * @param taskFunctions - Task function(s) processed by the worker when the pool's `execution` function is invoked.\n * @param opts - Options for the worker.\n */\n constructor(taskFunctions, opts = {}) {\n super('poolifier:thread-worker', isMainThread, parentPort, taskFunctions, opts);\n }\n /** @inheritDoc */\n handleReadyMessage(message) {\n if (message.workerId === this.id &&\n message.ready === false &&\n message.port != null) {\n try {\n this.port = message.port;\n this.port.on('message', this.messageListener.bind(this));\n this.sendToMainWorker({\n ready: true,\n taskFunctionNames: this.listTaskFunctionNames()\n });\n }\n catch {\n this.sendToMainWorker({\n ready: false,\n taskFunctionNames: this.listTaskFunctionNames()\n });\n }\n }\n }\n /** @inheritDoc */\n handleKillMessage(message) {\n super.handleKillMessage(message);\n this.port?.unref();\n this.port?.close();\n }\n /** @inheritDoc */\n get id() {\n return threadId;\n }\n /** @inheritDoc */\n sendToMainWorker(message) {\n this.port.postMessage({ ...message, workerId: this.id });\n }\n /** @inheritDoc */\n handleError(error) {\n return error;\n }\n}\n//# sourceMappingURL=thread-worker.js.map"],"names":["PoolTypes","Object","freeze","fixed","dynamic","PoolEvents","ready","busy","full","destroy","error","taskError","backPressure","WorkerTypes","thread","cluster","DEFAULT_TASK_NAME","EMPTY_FUNCTION","DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS","retries","runTime","median","waitTime","elu","DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS","aggregate","average","availableParallelism","os","cpus","Array","isArray","length","getWorkerType","worker","ThreadWorker","ClusterWorker","getWorkerId","threadId","id","dataSet","reduce","accumulator","number","sortedDataSet","slice","sort","a","b","round","num","scale","rounder","Math","pow","Number","EPSILON","isPlainObject","obj","constructor","prototype","toString","call","isKillBehavior","killBehavior","value","isAsyncFunction","fn","name","secureRandom","webcrypto","getRandomValues","Uint32Array","min","args","minimum","Infinity","max","maximum","WorkerChoiceStrategies","ROUND_ROBIN","LEAST_USED","LEAST_BUSY","LEAST_ELU","FAIR_SHARE","WEIGHTED_ROUND_ROBIN","INTERLEAVED_WEIGHTED_ROUND_ROBIN","Measurements","checkDynamicPoolSize","TypeError","isSafeInteger","RangeError","checkValidWorkerChoiceStrategy","workerChoiceStrategy","values","includes","Error","checkValidTasksQueueOptions","tasksQueueOptions","concurrency","size","updateMeasurementStatistics","measurementStatistics","measurementRequirements","measurementValue","history","push","KillBehaviors","SOFT","HARD","AbstractWorkerChoiceStrategy","pool","opts","nextWorkerNodeKey","previousWorkerNodeKey","strategyPolicy","dynamicWorkerUsage","dynamicWorkerReady","taskStatisticsRequirements","this","choose","bind","setTaskStatisticsRequirements","toggleMedianMeasurementStatisticsRequirements","measurementStatisticsRequirements","toggleMedian","resetWorkerNodeKeyProperties","setOptions","isWorkerNodeReady","workerNodeKey","workerNodes","info","hasWorkerNodeBackPressure","isWorkerNodeEligible","getWorkerNodeTaskRunTime","usage","getWorkerNodeTaskWaitTime","getWorkerNodeTaskElu","active","setPreviousWorkerNodeKey","checkNextWorkerNodeEligibility","undefined","computeDefaultWorkerWeight","cpusCycleTimeWeight","cpu","numberOfDigits","speed","FairShareWorkerChoiceStrategy","super","reset","workerNode","strategyData","virtualTaskEndTimestamp","update","computeWorkerNodeVirtualTaskEndTimestamp","fairShareNextWorkerNodeKey","remove","minWorkerNodeKey","getWorkerNodeVirtualTaskEndTimestamp","getWorkerNodeVirtualTaskStartTimestamp","workerNodeVirtualTaskStartTimestamp","measurement","now","performance","InterleavedWeightedRoundRobinWorkerChoiceStrategy","roundId","defaultWorkerWeight","roundWeights","workerNodeId","workerNodeVirtualTaskRunTime","getRoundWeights","roundIndex","workerWeight","weights","interleavedWeightedRoundRobinNextWorkerNodeId","Set","LeastBusyWorkerChoiceStrategy","leastBusyNextWorkerNodeKey","LeastUsedWorkerChoiceStrategy","leastUsedNextWorkerNodeKey","tasks","executed","executing","queued","LeastEluWorkerChoiceStrategy","leastEluNextWorkerNodeKey","RoundRobinWorkerChoiceStrategy","chosenWorkerNodeKey","roundRobinNextWorkerNodeKey","WeightedRoundRobinWorkerChoiceStrategy","weightedRoundRobinNextWorkerNodeKey","WorkerChoiceStrategyContext","workerChoiceStrategies","retriesCount","execute","Map","getStrategyPolicy","get","getTaskStatisticsRequirements","setWorkerChoiceStrategy","CircularArray","items","checkSize","arguments","splice","unshift","concat","concatenatedCircularArray","start","deleteCount","itemsRemoved","itemsOverflowing","resize","i","pop","empty","Node","data","next","prev","Deque","head","tail","maxSize","clear","node","incrementSize","shift","peekFirst","peekLast","Symbol","iterator","done","ret","backward","WorkerNode","messageChannel","tasksQueueBackPressureSize","onBackPressure","onEmptyQueue","tasksQueue","onBackPressureStarted","onEmptyQueueCount","taskFunctionsUsage","checkWorkerNodeArguments","initWorkerInfo","initWorkerUsage","type","MessageChannel","tasksQueueSize","enqueueTask","task","hasBackPressure","unshiftTask","dequeueTask","startOnEmptyQueue","catch","popTask","clearTasksQueue","resetUsage","closeChannel","port1","unref","port2","close","getTaskFunctionWorkerUsage","taskFunctionNames","has","set","initTaskFunctionWorkerUsage","deleteTaskFunctionWorkerUsage","delete","async","ms","Promise","resolve","setTimeout","sleep","retryNumber","delayFactor","delay","exponentialDelay","getTasksQueueSize","getTasksQueueMaxSize","maxQueued","stolen","failed","idle","getTaskFunctionQueueSize","taskFunctionQueueSize","AbstractPool","numberOfWorkers","filePath","emitter","promiseResponseMap","workerChoiceStrategyContext","taskFunctions","started","starting","startTimestamp","isMain","trim","existsSync","checkFilePath","checkNumberOfWorkers","checkPoolOptions","chooseWorkerNode","executeTask","enableEvents","initializeEventEmitter","workerChoiceStrategyOptions","setupHook","startWorkers","checkValidWorkerChoiceStrategyOptions","restartWorkerOnError","enableTasksQueue","buildTasksQueueOptions","keys","EventEmitterAsyncResource","version","strategy","minSize","utilization","idleWorkerNodes","busyWorkerNodes","executedTasks","executingTasks","queuedTasks","maxQueuedTasks","stolenTasks","failedTasks","map","poolTimeCapacity","checkMessageWorkerId","message","workerId","getWorkerNodeKeyByWorkerId","getWorkerNodeKeyByWorker","findIndex","setWorkerChoiceStrategyOptions","entries","sendStatisticsMessageToWorker","enable","unsetTaskStealing","unsetTasksStealingOnBackPressure","flushTasksQueues","setTasksQueueOptions","setTasksQueueSize","taskStealing","setTaskStealing","tasksStealingOnBackPressure","setTasksStealingOnBackPressure","taskStealingOnEmptyQueue","internalBusy","sendTaskFunctionOperationToWorker","reject","taskFunctionOperationListener","getWorkerInfo","taskFunctionOperationStatus","taskFunctionOperation","workerError","deregisterWorkerMessageListener","registerWorkerMessageListener","sendToWorker","sendTaskFunctionOperationToWorkers","responsesReceived","taskFunctionOperationsListener","every","some","errorResponse","find","response","hasTaskFunction","addTaskFunction","opResult","taskFunctionName","taskFunction","removeTaskFunction","deleteTaskFunctionWorkerUsages","listTaskFunctionNames","setDefaultTaskFunction","shallExecuteTask","transferList","timestamp","taskId","randomUUID","createAndSetupWorkerNode","all","_","destroyWorkerNode","emit","emitDestroy","sendKillMessageToWorker","kill","beforeTaskExecutionHook","workerUsage","updateWaitTimeWorkerUsage","shallUpdateTaskFunctionWorkerUsage","taskFunctionWorkerUsage","afterTaskExecutionHook","updateTaskStatisticsWorkerUsage","updateRunTimeWorkerUsage","updateEluWorkerUsage","taskPerformance","workerInfo","workerTaskStatistics","taskWaitTime","eluTaskStatisticsRequirements","shallCreateDynamicWorker","createAndSetupDynamicWorkerNode","createWorker","on","onlineHandler","messageHandler","errorHandler","redistributeQueuedTasks","exitHandler","once","removeWorkerNode","addWorkerNode","afterWorkerNodeSetup","localWorkerNodeKey","checkActive","checkAndEmitDynamicWorkerCreationEvents","workerListener","sendStartupMessageToWorker","statistics","destinationWorkerNodeKey","updateTaskStolenStatisticsWorkerUsage","taskName","sourceWorkerNode","workerNodeA","workerNodeB","handleWorkerReadyResponse","handleTaskExecutionResponse","promiseResponse","checkAndEmitTaskExecutionEvents","checkAndEmitTaskQueuingEvents","flushTasksQueue","FixedClusterPool","setupPrimary","settings","exec","isPrimary","waitWorkerExit","disconnect","send","listener","registerOnceWorkerMessageListener","off","fork","env","DynamicClusterPool","FixedThreadPool","numberOfThreads","isMainThread","terminate","postMessage","port","Worker","SHARE_ENV","workerOptions","DynamicThreadPool","checkValidTaskFunctionEntry","checkTaskFunctionName","DEFAULT_MAX_INACTIVE_TIME","DEFAULT_WORKER_OPTIONS","maxInactiveTime","killHandler","AbstractWorker","AsyncResource","mainWorker","lastTaskTimestamp","activeInterval","checkTaskFunctions","checkWorkerOptions","getMainWorker","handleReadyMessage","checkValidWorkerOptions","boundFn","firstEntry","status","sendTaskFunctionNamesToMainWorker","deleteStatus","names","defaultTaskFunctionName","indexOf","filter","messageListener","startCheckActive","stopCheckActive","handleTaskFunctionOperationMessage","run","handleKillMessage","Function","sendToMainWorker","handleError","then","finally","setInterval","clearInterval","runInAsyncScope","runAsync","runSync","beginTaskPerformance","res","endTaskPerformance","updateLastTaskTimestamp","checkStatistics","eventLoopUtilization","parentPort"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
3
|
"name": "poolifier",
|
|
4
|
-
"version": "2.7.
|
|
4
|
+
"version": "2.7.3",
|
|
5
5
|
"description": "Fast and small Node.js Worker_Threads and Cluster Worker Pool",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "./lib/index.js",
|
|
@@ -90,18 +90,18 @@
|
|
|
90
90
|
"@release-it/keep-a-changelog": "^4.0.0",
|
|
91
91
|
"@rollup/plugin-terser": "^0.4.3",
|
|
92
92
|
"@rollup/plugin-typescript": "^11.1.3",
|
|
93
|
-
"@types/node": "^20.6.
|
|
93
|
+
"@types/node": "^20.6.4",
|
|
94
94
|
"@typescript-eslint/eslint-plugin": "^6.7.2",
|
|
95
95
|
"@typescript-eslint/parser": "^6.7.2",
|
|
96
96
|
"benchmark": "^2.1.4",
|
|
97
97
|
"c8": "^8.0.1",
|
|
98
|
-
"eslint": "^8.
|
|
98
|
+
"eslint": "^8.50.0",
|
|
99
99
|
"eslint-config-standard": "^17.1.0",
|
|
100
|
-
"eslint-config-standard-with-typescript": "^39.
|
|
100
|
+
"eslint-config-standard-with-typescript": "^39.1.0",
|
|
101
101
|
"eslint-define-config": "^1.23.0",
|
|
102
|
-
"eslint-import-resolver-typescript": "^3.6.
|
|
102
|
+
"eslint-import-resolver-typescript": "^3.6.1",
|
|
103
103
|
"eslint-plugin-import": "^2.28.1",
|
|
104
|
-
"eslint-plugin-jsdoc": "^46.8.
|
|
104
|
+
"eslint-plugin-jsdoc": "^46.8.2",
|
|
105
105
|
"eslint-plugin-n": "^16.1.0",
|
|
106
106
|
"eslint-plugin-promise": "^6.1.1",
|
|
107
107
|
"eslint-plugin-spellcheck": "^0.0.20",
|
|
@@ -113,8 +113,8 @@
|
|
|
113
113
|
"mocha": "^10.2.0",
|
|
114
114
|
"mochawesome": "^7.1.3",
|
|
115
115
|
"prettier": "^3.0.3",
|
|
116
|
-
"release-it": "^16.
|
|
117
|
-
"rollup": "^3.29.
|
|
116
|
+
"release-it": "^16.2.0",
|
|
117
|
+
"rollup": "^3.29.3",
|
|
118
118
|
"rollup-plugin-analyzer": "^4.0.0",
|
|
119
119
|
"rollup-plugin-command": "^1.1.3",
|
|
120
120
|
"rollup-plugin-delete": "^2.0.0",
|