average,
isKillBehavior,
isPlainObject,
+ max,
median,
+ min,
round,
updateMeasurementStatistics
} from '../utils'
}
if (
tasksQueueOptions?.concurrency != null &&
- !Number.isSafeInteger(tasksQueueOptions.concurrency)
+ !Number.isSafeInteger(tasksQueueOptions?.concurrency)
) {
throw new TypeError(
'Invalid worker node tasks concurrency: must be an integer'
}
if (
tasksQueueOptions?.concurrency != null &&
- tasksQueueOptions.concurrency <= 0
+ tasksQueueOptions?.concurrency <= 0
) {
throw new RangeError(
- `Invalid worker node tasks concurrency: ${tasksQueueOptions.concurrency} is a negative integer or zero`
+ `Invalid worker node tasks concurrency: ${tasksQueueOptions?.concurrency} is a negative integer or zero`
)
}
if (tasksQueueOptions?.queueMaxSize != null) {
}
if (
tasksQueueOptions?.size != null &&
- !Number.isSafeInteger(tasksQueueOptions.size)
+ !Number.isSafeInteger(tasksQueueOptions?.size)
) {
throw new TypeError(
'Invalid worker node tasks queue size: must be an integer'
)
}
- if (tasksQueueOptions?.size != null && tasksQueueOptions.size <= 0) {
+ if (tasksQueueOptions?.size != null && tasksQueueOptions?.size <= 0) {
throw new RangeError(
- `Invalid worker node tasks queue size: ${tasksQueueOptions.size} is a negative integer or zero`
+ `Invalid worker node tasks queue size: ${tasksQueueOptions?.size} is a negative integer or zero`
)
}
}
.runTime.aggregate && {
runTime: {
minimum: round(
- Math.min(
+ min(
...this.workerNodes.map(
(workerNode) => workerNode.usage.runTime?.minimum ?? Infinity
)
)
),
maximum: round(
- Math.max(
+ max(
...this.workerNodes.map(
(workerNode) => workerNode.usage.runTime?.maximum ?? -Infinity
)
.waitTime.aggregate && {
waitTime: {
minimum: round(
- Math.min(
+ min(
...this.workerNodes.map(
(workerNode) => workerNode.usage.waitTime?.minimum ?? Infinity
)
)
),
maximum: round(
- Math.max(
+ max(
...this.workerNodes.map(
(workerNode) => workerNode.usage.waitTime?.maximum ?? -Infinity
)
}
const timestamp = performance.now()
const workerNodeKey = this.chooseWorkerNode()
- const workerInfo = this.getWorkerInfo(workerNodeKey) as WorkerInfo
+ const workerInfo = this.getWorkerInfo(workerNodeKey)
const task: Task<Data> = {
name: name ?? DEFAULT_TASK_NAME,
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
worker.on('error', this.opts.errorHandler ?? EMPTY_FUNCTION)
worker.on('error', (error) => {
const workerNodeKey = this.getWorkerNodeKeyByWorker(worker)
- const workerInfo = this.getWorkerInfo(workerNodeKey) as WorkerInfo
+ const workerInfo = this.getWorkerInfo(workerNodeKey)
workerInfo.ready = false
this.workerNodes[workerNodeKey].closeChannel()
this.emitter?.emit(PoolEvents.error, error)
})
}
})
- const workerInfo = this.getWorkerInfo(workerNodeKey) as WorkerInfo
+ const workerInfo = this.getWorkerInfo(workerNodeKey)
this.sendToWorker(workerNodeKey, {
checkActive: true,
workerId: workerInfo.id as number
elu: this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
.elu.aggregate
},
- workerId: (this.getWorkerInfo(workerNodeKey) as WorkerInfo).id as number
+ workerId: this.getWorkerInfo(workerNodeKey).id as number
})
}
private redistributeQueuedTasks (workerNodeKey: number): void {
while (this.tasksQueueSize(workerNodeKey) > 0) {
- let destinationWorkerNodeKey!: number
- let minQueuedTasks = Infinity
- for (const [workerNodeId, workerNode] of this.workerNodes.entries()) {
- if (workerNode.info.ready && workerNodeId !== workerNodeKey) {
- if (workerNode.usage.tasks.queued === 0) {
- destinationWorkerNodeKey = workerNodeId
- break
- }
- if (workerNode.usage.tasks.queued < minQueuedTasks) {
- minQueuedTasks = workerNode.usage.tasks.queued
- destinationWorkerNodeKey = workerNodeId
- }
- }
+ const destinationWorkerNodeKey = this.workerNodes.reduce(
+ (minWorkerNodeKey, workerNode, workerNodeKey, workerNodes) => {
+ return workerNode.info.ready &&
+ workerNode.usage.tasks.queued <
+ workerNodes[minWorkerNodeKey].usage.tasks.queued
+ ? workerNodeKey
+ : minWorkerNodeKey
+ },
+ 0
+ )
+ const destinationWorkerNode = this.workerNodes[destinationWorkerNodeKey]
+ const task = {
+ ...(this.dequeueTask(workerNodeKey) as Task<Data>),
+ workerId: destinationWorkerNode.info.id as number
}
- if (destinationWorkerNodeKey != null) {
- const destinationWorkerNode = this.workerNodes[destinationWorkerNodeKey]
- const task = {
- ...(this.dequeueTask(workerNodeKey) as Task<Data>),
- workerId: destinationWorkerNode.info.id as number
- }
- if (this.shallExecuteTask(destinationWorkerNodeKey)) {
- this.executeTask(destinationWorkerNodeKey, task)
- } else {
- this.enqueueTask(destinationWorkerNodeKey, task)
- }
+ if (this.shallExecuteTask(destinationWorkerNodeKey)) {
+ this.executeTask(destinationWorkerNodeKey, task)
+ } else {
+ this.enqueueTask(destinationWorkerNodeKey, task)
}
}
}
(workerNodeA, workerNodeB) =>
workerNodeB.usage.tasks.queued - workerNodeA.usage.tasks.queued
)
- for (const sourceWorkerNode of workerNodes) {
- if (sourceWorkerNode.usage.tasks.queued === 0) {
- break
+ const sourceWorkerNode = workerNodes.find(
+ (workerNode) =>
+ workerNode.info.ready &&
+ workerNode.info.id !== workerId &&
+ workerNode.usage.tasks.queued > 0
+ )
+ if (sourceWorkerNode != null) {
+ const task = {
+ ...(sourceWorkerNode.popTask() as Task<Data>),
+ workerId: destinationWorkerNode.info.id as number
}
- if (
- sourceWorkerNode.info.ready &&
- sourceWorkerNode.info.id !== workerId &&
- sourceWorkerNode.usage.tasks.queued > 0
- ) {
- const task = {
- ...(sourceWorkerNode.popTask() as Task<Data>),
- workerId: destinationWorkerNode.info.id as number
- }
- if (this.shallExecuteTask(destinationWorkerNodeKey)) {
- this.executeTask(destinationWorkerNodeKey, task)
- } else {
- this.enqueueTask(destinationWorkerNodeKey, task)
- }
- this.updateTaskStolenStatisticsWorkerUsage(
- destinationWorkerNodeKey,
- task.name as string
- )
- break
+ if (this.shallExecuteTask(destinationWorkerNodeKey)) {
+ this.executeTask(destinationWorkerNodeKey, task)
+ } else {
+ this.enqueueTask(destinationWorkerNodeKey, task)
}
+ this.updateTaskStolenStatisticsWorkerUsage(
+ destinationWorkerNodeKey,
+ task.name as string
+ )
}
}
this.handleTaskExecutionResponse(message)
} else if (message.taskFunctions != null) {
// Task functions message received from worker
- (
- this.getWorkerInfo(
- this.getWorkerNodeKeyByWorkerId(message.workerId)
- ) as WorkerInfo
+ this.getWorkerInfo(
+ this.getWorkerNodeKeyByWorkerId(message.workerId)
).taskFunctions = message.taskFunctions
}
}
}
const workerInfo = this.getWorkerInfo(
this.getWorkerNodeKeyByWorkerId(message.workerId)
- ) as WorkerInfo
+ )
workerInfo.ready = message.ready as boolean
workerInfo.taskFunctions = message.taskFunctions
if (this.emitter != null && this.ready) {
* @param workerNodeKey - The worker node key.
* @returns The worker information.
*/
- protected getWorkerInfo (workerNodeKey: number): WorkerInfo | undefined {
- return this.workerNodes[workerNodeKey]?.info
+ protected getWorkerInfo (workerNodeKey: number): WorkerInfo {
+ return this.workerNodes[workerNodeKey].info
}
/**