From 5df69fabd77b3ec4137a6382e2d84791bf0fe85d Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Fri, 9 Jun 2023 18:52:39 +0200 Subject: [PATCH] feat: add statistics accounting to ELU fields MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- src/pools/abstract-pool.ts | 67 ++- .../abstract-worker-choice-strategy.ts | 36 +- .../fair-share-worker-choice-strategy.ts | 6 +- .../least-busy-worker-choice-strategy.ts | 6 +- .../least-elu-worker-choice-strategy.ts | 8 +- .../selection-strategies-types.ts | 10 +- ...hted-round-robin-worker-choice-strategy.ts | 6 +- src/pools/worker.ts | 16 +- src/utils.ts | 3 +- tests/pools/abstract/abstract-pool.test.js | 107 ++++- .../selection-strategies.test.js | 381 +++++++++++++++--- 11 files changed, 543 insertions(+), 103 deletions(-) diff --git a/src/pools/abstract-pool.ts b/src/pools/abstract-pool.ts index 3c690fb8..f082b8d1 100644 --- a/src/pools/abstract-pool.ts +++ b/src/pools/abstract-pool.ts @@ -555,25 +555,46 @@ export abstract class AbstractPool< } private updateEluWorkerUsage ( - workerTasksUsage: WorkerUsage, + workerUsage: WorkerUsage, message: MessageValue ): void { - if (this.workerChoiceStrategyContext.getTaskStatisticsRequirements().elu) { + if ( + this.workerChoiceStrategyContext.getTaskStatisticsRequirements().elu + .aggregate + ) { + if (workerUsage.elu != null && message.taskPerformance?.elu != null) { + workerUsage.elu.idle.aggregate = + workerUsage.elu.idle.aggregate + message.taskPerformance.elu.idle + workerUsage.elu.active.aggregate = + workerUsage.elu.active.aggregate + message.taskPerformance.elu.active + workerUsage.elu.utilization = + (workerUsage.elu.utilization + + message.taskPerformance.elu.utilization) / + 2 + } else if (message.taskPerformance?.elu != null) { + workerUsage.elu.idle.aggregate = message.taskPerformance.elu.idle + workerUsage.elu.active.aggregate = message.taskPerformance.elu.active + workerUsage.elu.utilization = message.taskPerformance.elu.utilization + } if ( - workerTasksUsage.elu != null && + 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 && message.taskPerformance?.elu != null ) { - workerTasksUsage.elu = { - idle: workerTasksUsage.elu.idle + message.taskPerformance.elu.idle, - active: - workerTasksUsage.elu.active + message.taskPerformance.elu.active, - utilization: - (workerTasksUsage.elu.utilization + - message.taskPerformance.elu.utilization) / - 2 - } - } else if (message.taskPerformance?.elu != null) { - workerTasksUsage.elu = message.taskPerformance.elu + 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) } } } @@ -829,7 +850,7 @@ export abstract class AbstractPool< this.workerChoiceStrategyContext.getTaskStatisticsRequirements() .runTime.aggregate, elu: this.workerChoiceStrategyContext.getTaskStatisticsRequirements() - .elu + .elu.aggregate } }) } @@ -849,7 +870,21 @@ export abstract class AbstractPool< median: 0, history: new CircularArray() }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: new CircularArray() + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: new CircularArray() + }, + utilization: 0 + } } } diff --git a/src/pools/selection-strategies/abstract-worker-choice-strategy.ts b/src/pools/selection-strategies/abstract-worker-choice-strategy.ts index 18b47a1d..8f71b502 100644 --- a/src/pools/selection-strategies/abstract-worker-choice-strategy.ts +++ b/src/pools/selection-strategies/abstract-worker-choice-strategy.ts @@ -36,7 +36,11 @@ export abstract class AbstractWorkerChoiceStrategy< average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } } /** @@ -87,6 +91,20 @@ export abstract class AbstractWorkerChoiceStrategy< this.taskStatisticsRequirements.waitTime.median = opts.waitTime .median as boolean } + if ( + this.taskStatisticsRequirements.elu.average && + opts.elu?.median === true + ) { + this.taskStatisticsRequirements.elu.average = false + this.taskStatisticsRequirements.elu.median = opts.elu.median as boolean + } + if ( + this.taskStatisticsRequirements.elu.median && + opts.elu?.median === false + ) { + this.taskStatisticsRequirements.elu.average = true + this.taskStatisticsRequirements.elu.median = opts.elu.median as boolean + } } /** @inheritDoc */ @@ -144,12 +162,26 @@ export abstract class AbstractWorkerChoiceStrategy< * @param workerNodeKey - The worker node key. * @returns The worker task wait time. */ - protected getWorkerWaitTime (workerNodeKey: number): number { + protected getWorkerTaskWaitTime (workerNodeKey: number): number { return this.taskStatisticsRequirements.waitTime.median ? this.pool.workerNodes[workerNodeKey].workerUsage.runTime.median : this.pool.workerNodes[workerNodeKey].workerUsage.runTime.average } + /** + * Gets the worker task ELU. + * If the task statistics require the ELU, the average ELU is returned. + * If the task statistics require the ELU, the median ELU is returned. + * + * @param workerNodeKey - The worker node key. + * @returns The worker task ELU. + */ + protected getWorkerTaskElu (workerNodeKey: number): number { + return this.taskStatisticsRequirements.elu.median + ? this.pool.workerNodes[workerNodeKey].workerUsage.elu.active.median + : this.pool.workerNodes[workerNodeKey].workerUsage.elu.active.average + } + protected computeDefaultWorkerWeight (): number { let cpusCycleTimeWeight = 0 for (const cpu of cpus()) { diff --git a/src/pools/selection-strategies/fair-share-worker-choice-strategy.ts b/src/pools/selection-strategies/fair-share-worker-choice-strategy.ts index 4ea68d40..52b25fb9 100644 --- a/src/pools/selection-strategies/fair-share-worker-choice-strategy.ts +++ b/src/pools/selection-strategies/fair-share-worker-choice-strategy.ts @@ -35,7 +35,11 @@ export class FairShareWorkerChoiceStrategy< average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } } /** diff --git a/src/pools/selection-strategies/least-busy-worker-choice-strategy.ts b/src/pools/selection-strategies/least-busy-worker-choice-strategy.ts index 8afd2c36..58fbb51e 100644 --- a/src/pools/selection-strategies/least-busy-worker-choice-strategy.ts +++ b/src/pools/selection-strategies/least-busy-worker-choice-strategy.ts @@ -34,7 +34,11 @@ export class LeastBusyWorkerChoiceStrategy< average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } } /** @inheritDoc */ diff --git a/src/pools/selection-strategies/least-elu-worker-choice-strategy.ts b/src/pools/selection-strategies/least-elu-worker-choice-strategy.ts index 9f6ddbf3..35ab69d0 100644 --- a/src/pools/selection-strategies/least-elu-worker-choice-strategy.ts +++ b/src/pools/selection-strategies/least-elu-worker-choice-strategy.ts @@ -34,7 +34,11 @@ export class LeastEluWorkerChoiceStrategy< average: false, median: false }, - elu: true + elu: { + aggregate: true, + average: false, + median: false + } } /** @inheritDoc */ @@ -62,7 +66,7 @@ export class LeastEluWorkerChoiceStrategy< let leastEluWorkerNodeKey!: number for (const [workerNodeKey, workerNode] of this.pool.workerNodes.entries()) { const workerUsage = workerNode.workerUsage - const workerElu = workerUsage.elu?.active ?? 0 + const workerElu = workerUsage.elu?.active.aggregate ?? 0 if (workerElu === 0) { return workerNodeKey } else if (workerElu < minWorkerElu) { diff --git a/src/pools/selection-strategies/selection-strategies-types.ts b/src/pools/selection-strategies/selection-strategies-types.ts index 0fbb4d4d..c578ddc3 100644 --- a/src/pools/selection-strategies/selection-strategies-types.ts +++ b/src/pools/selection-strategies/selection-strategies-types.ts @@ -67,6 +67,12 @@ export interface WorkerChoiceStrategyOptions { * @defaultValue \{ median: false \} */ waitTime?: MeasurementOptions + /** + * Event loop utilization options. + * + * @defaultValue \{ median: false \} + */ + elu?: MeasurementOptions /** * Worker weights to use for weighted round robin worker selection strategy. * Weight is the tasks maximum average or median runtime in milliseconds. @@ -111,9 +117,9 @@ export interface TaskStatisticsRequirements { */ waitTime: MeasurementStatisticsRequirements /** - * Event loop utilization. + * Tasks event loop utilization requirements. */ - elu: boolean + elu: MeasurementStatisticsRequirements } /** diff --git a/src/pools/selection-strategies/weighted-round-robin-worker-choice-strategy.ts b/src/pools/selection-strategies/weighted-round-robin-worker-choice-strategy.ts index 4fcbeeda..1ce60419 100644 --- a/src/pools/selection-strategies/weighted-round-robin-worker-choice-strategy.ts +++ b/src/pools/selection-strategies/weighted-round-robin-worker-choice-strategy.ts @@ -35,7 +35,11 @@ export class WeightedRoundRobinWorkerChoiceStrategy< average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } } /** diff --git a/src/pools/worker.ts b/src/pools/worker.ts index 70e4a7ed..598e6be8 100644 --- a/src/pools/worker.ts +++ b/src/pools/worker.ts @@ -1,4 +1,3 @@ -import type { EventLoopUtilization } from 'node:perf_hooks' import type { CircularArray } from '../circular-array' import type { Queue } from '../queue' @@ -80,6 +79,17 @@ export interface MeasurementStatistics { history: CircularArray } +/** + * Event loop utilization measurement statistics. + * + * @internal + */ +export interface EventLoopUtilizationMeasurementStatistics { + idle: MeasurementStatistics + active: MeasurementStatistics + utilization: number +} + /** * Task statistics. * @@ -123,9 +133,9 @@ export interface WorkerUsage { */ waitTime: MeasurementStatistics /** - * Event loop utilization. + * Tasks event loop utilization statistics. */ - elu: EventLoopUtilization | undefined + elu: EventLoopUtilizationMeasurementStatistics } /** diff --git a/src/utils.ts b/src/utils.ts index 7b921ffa..6e5f7252 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -13,7 +13,8 @@ export const EMPTY_FUNCTION: () => void = Object.freeze(() => { export const DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS: WorkerChoiceStrategyOptions = { runTime: { median: false }, - waitTime: { median: false } + waitTime: { median: false }, + elu: { median: false } } /** diff --git a/tests/pools/abstract/abstract-pool.test.js b/tests/pools/abstract/abstract-pool.test.js index 12237d93..25566a6a 100644 --- a/tests/pools/abstract/abstract-pool.test.js +++ b/tests/pools/abstract/abstract-pool.test.js @@ -94,7 +94,8 @@ describe('Abstract pool test suite', () => { ) expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({ runTime: { median: false }, - waitTime: { median: false } + waitTime: { median: false }, + elu: { median: false } }) expect(pool.opts.messageHandler).toBeUndefined() expect(pool.opts.errorHandler).toBeUndefined() @@ -184,13 +185,15 @@ describe('Abstract pool test suite', () => { ) expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({ runTime: { median: false }, - waitTime: { median: false } + waitTime: { median: false }, + elu: { median: false } }) for (const [, workerChoiceStrategy] of pool.workerChoiceStrategyContext .workerChoiceStrategies) { expect(workerChoiceStrategy.opts).toStrictEqual({ runTime: { median: false }, - waitTime: { median: false } + waitTime: { median: false }, + elu: { median: false } }) } expect( @@ -206,7 +209,11 @@ describe('Abstract pool test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) pool.setWorkerChoiceStrategyOptions({ runTime: { median: true } }) expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({ @@ -231,7 +238,11 @@ describe('Abstract pool test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) pool.setWorkerChoiceStrategyOptions({ runTime: { median: false } }) expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({ @@ -256,7 +267,11 @@ describe('Abstract pool test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) await pool.destroy() }) @@ -377,7 +392,21 @@ describe('Abstract pool test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) } await pool.destroy() @@ -426,7 +455,21 @@ describe('Abstract pool test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) } await Promise.all(promises) @@ -450,7 +493,21 @@ describe('Abstract pool test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) } await pool.destroy() @@ -488,7 +545,21 @@ describe('Abstract pool test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0) expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual( @@ -516,7 +587,21 @@ describe('Abstract pool test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) expect(workerNode.workerUsage.runTime.history.length).toBe(0) expect(workerNode.workerUsage.waitTime.history.length).toBe(0) diff --git a/tests/pools/selection-strategies/selection-strategies.test.js b/tests/pools/selection-strategies/selection-strategies.test.js index dbe286b4..9b581ff5 100644 --- a/tests/pools/selection-strategies/selection-strategies.test.js +++ b/tests/pools/selection-strategies/selection-strategies.test.js @@ -135,7 +135,11 @@ describe('Selection strategies test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) await pool.destroy() pool = new DynamicThreadPool( @@ -157,7 +161,11 @@ describe('Selection strategies test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) // We need to clean up the resources after our test await pool.destroy() @@ -196,7 +204,21 @@ describe('Selection strategies test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) } expect( @@ -242,7 +264,21 @@ describe('Selection strategies test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) } expect( @@ -340,7 +376,11 @@ describe('Selection strategies test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) await pool.destroy() pool = new DynamicThreadPool( @@ -362,7 +402,11 @@ describe('Selection strategies test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) // We need to clean up the resources after our test await pool.destroy() @@ -401,7 +445,21 @@ describe('Selection strategies test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) } // We need to clean up the resources after our test @@ -442,8 +500,21 @@ describe('Selection strategies test suite', () => { median: 0, history: expect.any(CircularArray) }, - - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) } // We need to clean up the resources after our test @@ -470,7 +541,11 @@ describe('Selection strategies test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) await pool.destroy() pool = new DynamicThreadPool( @@ -492,7 +567,11 @@ describe('Selection strategies test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) // We need to clean up the resources after our test await pool.destroy() @@ -531,7 +610,21 @@ describe('Selection strategies test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0) expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual( @@ -580,7 +673,21 @@ describe('Selection strategies test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0) expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual( @@ -613,7 +720,11 @@ describe('Selection strategies test suite', () => { average: false, median: false }, - elu: true + elu: { + aggregate: true, + average: false, + median: false + } }) await pool.destroy() pool = new DynamicThreadPool( @@ -635,7 +746,11 @@ describe('Selection strategies test suite', () => { average: false, median: false }, - elu: true + elu: { + aggregate: true, + average: false, + median: false + } }) // We need to clean up the resources after our test await pool.destroy() @@ -655,7 +770,7 @@ describe('Selection strategies test suite', () => { } await Promise.all(promises) for (const workerNode of pool.workerNodes) { - const expectedWorkerUsage = { + expect(workerNode.workerUsage).toStrictEqual({ tasks: { executed: expect.any(Number), executing: 0, @@ -673,27 +788,29 @@ describe('Selection strategies test suite', () => { average: 0, median: 0, history: expect.any(CircularArray) + }, + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: expect.any(Number), + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: expect.any(Number) } - } - if (workerNode.workerUsage.elu === undefined) { - expect(workerNode.workerUsage).toStrictEqual({ - ...expectedWorkerUsage, - elu: undefined - }) - } else { - expect(workerNode.workerUsage).toStrictEqual({ - ...expectedWorkerUsage, - elu: { - active: expect.any(Number), - idle: 0, - utilization: 1 - } - }) - } + }) expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0) expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual( max * maxMultiplier ) + expect(workerNode.workerUsage.elu.utilization).toBeGreaterThanOrEqual(0) + expect(workerNode.workerUsage.elu.utilization).toBeLessThanOrEqual(1) } // We need to clean up the resources after our test await pool.destroy() @@ -714,7 +831,7 @@ describe('Selection strategies test suite', () => { } await Promise.all(promises) for (const workerNode of pool.workerNodes) { - const expectedWorkerUsage = { + expect(workerNode.workerUsage).toStrictEqual({ tasks: { executed: expect.any(Number), executing: 0, @@ -732,27 +849,29 @@ describe('Selection strategies test suite', () => { average: 0, median: 0, history: expect.any(CircularArray) + }, + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: expect.any(Number), + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: expect.any(Number) } - } - if (workerNode.workerUsage.elu === undefined) { - expect(workerNode.workerUsage).toStrictEqual({ - ...expectedWorkerUsage, - elu: undefined - }) - } else { - expect(workerNode.workerUsage).toStrictEqual({ - ...expectedWorkerUsage, - elu: { - active: expect.any(Number), - idle: 0, - utilization: 1 - } - }) - } + }) expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0) expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual( max * maxMultiplier ) + expect(workerNode.workerUsage.elu.utilization).toBeGreaterThanOrEqual(0) + expect(workerNode.workerUsage.elu.utilization).toBeLessThanOrEqual(1) } // We need to clean up the resources after our test await pool.destroy() @@ -778,7 +897,11 @@ describe('Selection strategies test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) await pool.destroy() pool = new DynamicThreadPool( @@ -800,7 +923,11 @@ describe('Selection strategies test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) // We need to clean up the resources after our test await pool.destroy() @@ -839,7 +966,21 @@ describe('Selection strategies test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThan(0) expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0) @@ -887,7 +1028,21 @@ describe('Selection strategies test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThan(0) expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0) @@ -940,7 +1095,21 @@ describe('Selection strategies test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThan(0) expect(workerNode.workerUsage.runTime.median).toBeGreaterThan(0) @@ -1048,7 +1217,11 @@ describe('Selection strategies test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) await pool.destroy() pool = new DynamicThreadPool( @@ -1070,7 +1243,11 @@ describe('Selection strategies test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) // We need to clean up the resources after our test await pool.destroy() @@ -1109,7 +1286,21 @@ describe('Selection strategies test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0) expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual( @@ -1166,7 +1357,21 @@ describe('Selection strategies test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0) expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual( @@ -1228,7 +1433,21 @@ describe('Selection strategies test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0) expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual( @@ -1350,7 +1569,11 @@ describe('Selection strategies test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) await pool.destroy() pool = new DynamicThreadPool( @@ -1372,7 +1595,11 @@ describe('Selection strategies test suite', () => { average: false, median: false }, - elu: false + elu: { + aggregate: false, + average: false, + median: false + } }) // We need to clean up the resources after our test await pool.destroy() @@ -1414,7 +1641,21 @@ describe('Selection strategies test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) } expect( @@ -1482,7 +1723,21 @@ describe('Selection strategies test suite', () => { median: 0, history: expect.any(CircularArray) }, - elu: undefined + elu: { + idle: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + active: { + aggregate: 0, + average: 0, + median: 0, + history: expect.any(CircularArray) + }, + utilization: 0 + } }) } expect( -- 2.34.1