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 => {
14 typeof filePath
!== 'string' ||
15 (typeof filePath
=== 'string' && filePath
.trim().length
=== 0)
17 throw new Error('Please specify a file with a worker implementation')
19 if (!existsSync(filePath
)) {
20 throw new Error(`Cannot find the worker file '${filePath}'`)
24 export const checkDynamicPoolSize
= (min
: number, max
: number): void => {
27 'Cannot instantiate a dynamic pool without specifying the maximum pool size'
29 } else if (!Number.isSafeInteger(max
)) {
31 'Cannot instantiate a dynamic pool with a non safe integer maximum pool size'
33 } else if (min
> max
) {
35 'Cannot instantiate a dynamic pool with a maximum pool size inferior to the minimum pool size'
37 } else if (max
=== 0) {
39 'Cannot instantiate a dynamic pool with a maximum pool size equal to zero'
41 } else if (min
=== max
) {
43 'Cannot instantiate a dynamic pool with a minimum pool size equal to the maximum pool size. Use a fixed pool instead'
48 export const checkValidWorkerChoiceStrategy
= (
49 workerChoiceStrategy
: WorkerChoiceStrategy
52 workerChoiceStrategy
!= null &&
53 !Object.values(WorkerChoiceStrategies
).includes(workerChoiceStrategy
)
55 throw new Error(`Invalid worker choice strategy '${workerChoiceStrategy}'`)
59 export const checkValidTasksQueueOptions
= (
60 tasksQueueOptions
: TasksQueueOptions
62 if (tasksQueueOptions
!= null && !isPlainObject(tasksQueueOptions
)) {
63 throw new TypeError('Invalid tasks queue options: must be a plain object')
66 tasksQueueOptions
?.concurrency
!= null &&
67 !Number.isSafeInteger(tasksQueueOptions
.concurrency
)
70 'Invalid worker node tasks concurrency: must be an integer'
74 tasksQueueOptions
?.concurrency
!= null &&
75 tasksQueueOptions
.concurrency
<= 0
78 `Invalid worker node tasks concurrency: ${tasksQueueOptions.concurrency} is a negative integer or zero`
82 tasksQueueOptions
?.size
!= null &&
83 !Number.isSafeInteger(tasksQueueOptions
.size
)
86 'Invalid worker node tasks queue size: must be an integer'
89 if (tasksQueueOptions
?.size
!= null && tasksQueueOptions
.size
<= 0) {
91 `Invalid worker node tasks queue size: ${tasksQueueOptions.size} is a negative integer or zero`
96 export const checkWorkerNodeArguments
= <Worker
extends IWorker
>(
98 tasksQueueBackPressureSize
: number
100 if (worker
== null) {
101 throw new TypeError('Cannot construct a worker node without a worker')
103 if (tasksQueueBackPressureSize
== null) {
105 'Cannot construct a worker node without a tasks queue back pressure size'
108 if (!Number.isSafeInteger(tasksQueueBackPressureSize
)) {
110 'Cannot construct a worker node with a tasks queue back pressure size that is not an integer'
113 if (tasksQueueBackPressureSize
<= 0) {
114 throw new RangeError(
115 'Cannot construct a worker node with a tasks queue back pressure size that is not a positive integer'
121 * Updates the given measurement statistics.
123 * @param measurementStatistics - The measurement statistics to update.
124 * @param measurementRequirements - The measurement statistics requirements.
125 * @param measurementValue - The measurement value.
126 * @param numberOfMeasurements - The number of measurements.
129 export const updateMeasurementStatistics
= (
130 measurementStatistics
: MeasurementStatistics
,
131 measurementRequirements
: MeasurementStatisticsRequirements
,
132 measurementValue
: number
134 if (measurementRequirements
.aggregate
) {
135 measurementStatistics
.aggregate
=
136 (measurementStatistics
.aggregate
?? 0) + measurementValue
137 measurementStatistics
.minimum
= min(
139 measurementStatistics
.minimum
?? Infinity
141 measurementStatistics
.maximum
= max(
143 measurementStatistics
.maximum
?? -Infinity
146 (measurementRequirements
.average
|| measurementRequirements
.median
) &&
147 measurementValue
!= null
149 measurementStatistics
.history
.push(measurementValue
)
150 if (measurementRequirements
.average
) {
151 measurementStatistics
.average
= average(measurementStatistics
.history
)
152 } else if (measurementStatistics
.average
!= null) {
153 delete measurementStatistics
.average
155 if (measurementRequirements
.median
) {
156 measurementStatistics
.median
= median(measurementStatistics
.history
)
157 } else if (measurementStatistics
.median
!= null) {
158 delete measurementStatistics
.median