1 import { existsSync
} from
'node:fs'
2 import { average
, isPlainObject
, max
, median
, min
} from
'../utils'
4 type MeasurementStatisticsRequirements
,
5 WorkerChoiceStrategies
,
6 type WorkerChoiceStrategy
7 } from
'./selection-strategies/selection-strategies-types'
8 import type { TasksQueueOptions
} from
'./pool'
9 import type { IWorker
, MeasurementStatistics
} from
'./worker'
11 export const checkFilePath
= (filePath
: string): void => {
12 if (!existsSync(filePath
)) {
13 throw new Error(`Cannot find the worker file '${filePath}'`)
17 export const checkDynamicPoolSize
= (min
: number, max
: number): void => {
20 'Cannot instantiate a dynamic pool without specifying the maximum pool size'
22 } else if (!Number.isSafeInteger(max
)) {
24 'Cannot instantiate a dynamic pool with a non safe integer maximum pool size'
26 } else if (min
> max
) {
28 'Cannot instantiate a dynamic pool with a maximum pool size inferior to the minimum pool size'
30 } else if (max
=== 0) {
32 'Cannot instantiate a dynamic pool with a maximum pool size equal to zero'
34 } else if (min
=== max
) {
36 'Cannot instantiate a dynamic pool with a minimum pool size equal to the maximum pool size. Use a fixed pool instead'
41 export const checkValidWorkerChoiceStrategy
= (
42 workerChoiceStrategy
: WorkerChoiceStrategy
45 workerChoiceStrategy
!= null &&
46 !Object.values(WorkerChoiceStrategies
).includes(workerChoiceStrategy
)
48 throw new Error(`Invalid worker choice strategy '${workerChoiceStrategy}'`)
52 export const checkValidTasksQueueOptions
= (
53 tasksQueueOptions
: TasksQueueOptions
55 if (tasksQueueOptions
!= null && !isPlainObject(tasksQueueOptions
)) {
56 throw new TypeError('Invalid tasks queue options: must be a plain object')
59 tasksQueueOptions
?.concurrency
!= null &&
60 !Number.isSafeInteger(tasksQueueOptions
.concurrency
)
63 'Invalid worker node tasks concurrency: must be an integer'
67 tasksQueueOptions
?.concurrency
!= null &&
68 tasksQueueOptions
.concurrency
<= 0
71 `Invalid worker node tasks concurrency: ${tasksQueueOptions.concurrency} is a negative integer or zero`
75 tasksQueueOptions
?.size
!= null &&
76 !Number.isSafeInteger(tasksQueueOptions
.size
)
79 'Invalid worker node tasks queue size: must be an integer'
82 if (tasksQueueOptions
?.size
!= null && tasksQueueOptions
.size
<= 0) {
84 `Invalid worker node tasks queue size: ${tasksQueueOptions.size} is a negative integer or zero`
89 export const checkWorkerNodeArguments
= <Worker
extends IWorker
>(
91 tasksQueueBackPressureSize
: number
94 throw new TypeError('Cannot construct a worker node without a worker')
96 if (tasksQueueBackPressureSize
== null) {
98 'Cannot construct a worker node without a tasks queue back pressure size'
101 if (!Number.isSafeInteger(tasksQueueBackPressureSize
)) {
103 'Cannot construct a worker node with a tasks queue back pressure size that is not an integer'
106 if (tasksQueueBackPressureSize
<= 0) {
107 throw new RangeError(
108 'Cannot construct a worker node with a tasks queue back pressure size that is not a positive integer'
114 * Updates the given measurement statistics.
116 * @param measurementStatistics - The measurement statistics to update.
117 * @param measurementRequirements - The measurement statistics requirements.
118 * @param measurementValue - The measurement value.
119 * @param numberOfMeasurements - The number of measurements.
122 export const updateMeasurementStatistics
= (
123 measurementStatistics
: MeasurementStatistics
,
124 measurementRequirements
: MeasurementStatisticsRequirements
,
125 measurementValue
: number
127 if (measurementRequirements
.aggregate
) {
128 measurementStatistics
.aggregate
=
129 (measurementStatistics
.aggregate
?? 0) + measurementValue
130 measurementStatistics
.minimum
= min(
132 measurementStatistics
.minimum
?? Infinity
134 measurementStatistics
.maximum
= max(
136 measurementStatistics
.maximum
?? -Infinity
139 (measurementRequirements
.average
|| measurementRequirements
.median
) &&
140 measurementValue
!= null
142 measurementStatistics
.history
.push(measurementValue
)
143 if (measurementRequirements
.average
) {
144 measurementStatistics
.average
= average(measurementStatistics
.history
)
145 } else if (measurementStatistics
.average
!= null) {
146 delete measurementStatistics
.average
148 if (measurementRequirements
.median
) {
149 measurementStatistics
.median
= median(measurementStatistics
.history
)
150 } else if (measurementStatistics
.median
!= null) {
151 delete measurementStatistics
.median