isKillBehavior,
isPlainObject,
median,
- round
+ round,
+ updateMeasurementStatistics
} from '../utils'
import { KillBehaviors } from '../worker/worker-options'
import {
WorkerUsage
} from './worker'
import {
+ type MeasurementStatisticsRequirements,
Measurements,
WorkerChoiceStrategies,
type WorkerChoiceStrategy,
>
/**
- * Whether the pool is starting.
+ * Whether the pool is starting or not.
*/
private readonly starting: boolean
/**
this.setupHook()
this.starting = true
- while (
- this.workerNodes.reduce(
- (accumulator, workerNode) =>
- !workerNode.info.dynamic ? accumulator + 1 : accumulator,
- 0
- ) < this.numberOfWorkers
- ) {
- this.createAndSetupWorker()
- }
+ this.startPool()
this.starting = false
this.startTimestamp = performance.now()
}
}
+ private startPool (): void {
+ while (
+ this.workerNodes.reduce(
+ (accumulator, workerNode) =>
+ !workerNode.info.dynamic ? accumulator + 1 : accumulator,
+ 0
+ ) < this.numberOfWorkers
+ ) {
+ this.createAndSetupWorker()
+ }
+ }
+
/** @inheritDoc */
public get info (): PoolInfo {
return {
workerUsage: WorkerUsage,
message: MessageValue<Response>
): void {
- if (
- this.workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime
- .aggregate
- ) {
- const taskRunTime = message.taskPerformance?.runTime ?? 0
- workerUsage.runTime.aggregate =
- (workerUsage.runTime.aggregate ?? 0) + taskRunTime
- workerUsage.runTime.minimum = Math.min(
- taskRunTime,
- workerUsage.runTime?.minimum ?? Infinity
- )
- workerUsage.runTime.maximum = Math.max(
- taskRunTime,
- workerUsage.runTime?.maximum ?? -Infinity
- )
- if (
- this.workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime
- .average &&
- workerUsage.tasks.executed !== 0
- ) {
- workerUsage.runTime.average =
- workerUsage.runTime.aggregate / workerUsage.tasks.executed
- }
- if (
- this.workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime
- .median &&
- message.taskPerformance?.runTime != null
- ) {
- workerUsage.runTime.history.push(message.taskPerformance.runTime)
- workerUsage.runTime.median = median(workerUsage.runTime.history)
- }
- }
+ updateMeasurementStatistics(
+ workerUsage.runTime,
+ this.workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime,
+ message.taskPerformance?.runTime ?? 0,
+ workerUsage.tasks.executed
+ )
}
private updateWaitTimeWorkerUsage (
): void {
const timestamp = performance.now()
const taskWaitTime = timestamp - (task.timestamp ?? timestamp)
- if (
- this.workerChoiceStrategyContext.getTaskStatisticsRequirements().waitTime
- .aggregate
- ) {
- workerUsage.waitTime.aggregate =
- (workerUsage.waitTime?.aggregate ?? 0) + taskWaitTime
- workerUsage.waitTime.minimum = Math.min(
- taskWaitTime,
- workerUsage.waitTime?.minimum ?? Infinity
- )
- workerUsage.waitTime.maximum = Math.max(
- taskWaitTime,
- workerUsage.waitTime?.maximum ?? -Infinity
- )
- if (
- this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
- .waitTime.average &&
- workerUsage.tasks.executed !== 0
- ) {
- workerUsage.waitTime.average =
- workerUsage.waitTime.aggregate / workerUsage.tasks.executed
- }
- if (
- this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
- .waitTime.median
- ) {
- workerUsage.waitTime.history.push(taskWaitTime)
- workerUsage.waitTime.median = median(workerUsage.waitTime.history)
- }
- }
+ updateMeasurementStatistics(
+ workerUsage.waitTime,
+ this.workerChoiceStrategyContext.getTaskStatisticsRequirements().waitTime,
+ taskWaitTime,
+ workerUsage.tasks.executed
+ )
}
private updateEluWorkerUsage (
workerUsage: WorkerUsage,
message: MessageValue<Response>
): void {
- if (
+ const eluTaskStatisticsRequirements: MeasurementStatisticsRequirements =
this.workerChoiceStrategyContext.getTaskStatisticsRequirements().elu
- .aggregate
- ) {
+ updateMeasurementStatistics(
+ workerUsage.elu.active,
+ eluTaskStatisticsRequirements,
+ message.taskPerformance?.elu?.active ?? 0,
+ workerUsage.tasks.executed
+ )
+ updateMeasurementStatistics(
+ workerUsage.elu.idle,
+ eluTaskStatisticsRequirements,
+ message.taskPerformance?.elu?.idle ?? 0,
+ workerUsage.tasks.executed
+ )
+ if (eluTaskStatisticsRequirements.aggregate) {
if (message.taskPerformance?.elu != null) {
- workerUsage.elu.idle.aggregate =
- (workerUsage.elu.idle?.aggregate ?? 0) +
- message.taskPerformance.elu.idle
- workerUsage.elu.active.aggregate =
- (workerUsage.elu.active?.aggregate ?? 0) +
- message.taskPerformance.elu.active
if (workerUsage.elu.utilization != null) {
workerUsage.elu.utilization =
(workerUsage.elu.utilization +
} else {
workerUsage.elu.utilization = message.taskPerformance.elu.utilization
}
- workerUsage.elu.idle.minimum = Math.min(
- message.taskPerformance.elu.idle,
- workerUsage.elu.idle?.minimum ?? Infinity
- )
- workerUsage.elu.idle.maximum = Math.max(
- message.taskPerformance.elu.idle,
- workerUsage.elu.idle?.maximum ?? -Infinity
- )
- workerUsage.elu.active.minimum = Math.min(
- message.taskPerformance.elu.active,
- workerUsage.elu.active?.minimum ?? Infinity
- )
- workerUsage.elu.active.maximum = Math.max(
- message.taskPerformance.elu.active,
- workerUsage.elu.active?.maximum ?? -Infinity
- )
- if (
- this.workerChoiceStrategyContext.getTaskStatisticsRequirements().elu
- .average &&
- workerUsage.tasks.executed !== 0
- ) {
- workerUsage.elu.idle.average =
- workerUsage.elu.idle.aggregate / workerUsage.tasks.executed
- workerUsage.elu.active.average =
- workerUsage.elu.active.aggregate / workerUsage.tasks.executed
- }
- if (
- this.workerChoiceStrategyContext.getTaskStatisticsRequirements().elu
- .median
- ) {
- workerUsage.elu.idle.history.push(message.taskPerformance.elu.idle)
- workerUsage.elu.active.history.push(
- message.taskPerformance.elu.active
- )
- workerUsage.elu.idle.median = median(workerUsage.elu.idle.history)
- workerUsage.elu.active.median = median(workerUsage.elu.active.history)
- }
}
}
}
const workerNodeKey = this.getWorkerNodeKey(worker)
const workerInfo = this.getWorkerInfo(workerNodeKey)
workerInfo.ready = false
- if (this.emitter != null) {
- this.emitter.emit(PoolEvents.error, error)
- }
+ this.emitter?.emit(PoolEvents.error, error)
if (this.opts.restartWorkerOnError === true && !this.starting) {
if (workerInfo.dynamic) {
this.createAndSetupDynamicWorker()
const promiseResponse = this.promiseResponseMap.get(message.id as string)
if (promiseResponse != null) {
if (message.taskError != null) {
- if (this.emitter != null) {
- this.emitter.emit(PoolEvents.taskError, message.taskError)
- }
+ this.emitter?.emit(PoolEvents.taskError, message.taskError)
promiseResponse.reject(message.taskError.message)
} else {
promiseResponse.resolve(message.data as Response)