From b529c323958350e8b54ccfb4096d0c661c975b71 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Thu, 6 Apr 2023 08:40:41 +0200 Subject: [PATCH] perf: pre-instantiate worker choice strategies 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 | 9 +++ .../worker-choice-strategy-context.ts | 77 +++++++----------- .../selection-strategies.test.js | 42 +++++----- .../worker-choice-strategy-context.test.js | 78 ------------------- 4 files changed, 57 insertions(+), 149 deletions(-) diff --git a/src/pools/abstract-pool.ts b/src/pools/abstract-pool.ts index 7b0e5bc7..476a5237 100644 --- a/src/pools/abstract-pool.ts +++ b/src/pools/abstract-pool.ts @@ -142,6 +142,15 @@ export abstract class AbstractPool< private checkPoolOptions (opts: PoolOptions): void { this.opts.workerChoiceStrategy = opts.workerChoiceStrategy ?? WorkerChoiceStrategies.ROUND_ROBIN + if ( + !Object.values(WorkerChoiceStrategies).includes( + this.opts.workerChoiceStrategy + ) + ) { + throw new Error( + `Invalid worker choice strategy '${this.opts.workerChoiceStrategy}'` + ) + } this.opts.enableEvents = opts.enableEvents ?? true } diff --git a/src/pools/selection-strategies/worker-choice-strategy-context.ts b/src/pools/selection-strategies/worker-choice-strategy-context.ts index 90c98c60..2d337387 100644 --- a/src/pools/selection-strategies/worker-choice-strategy-context.ts +++ b/src/pools/selection-strategies/worker-choice-strategy-context.ts @@ -24,10 +24,10 @@ export class WorkerChoiceStrategyContext< Data = unknown, Response = unknown > { - private readonly workerChoiceStrategies = new Map< + private readonly workerChoiceStrategies: Map< WorkerChoiceStrategy, IWorkerChoiceStrategy - >() + > /** * Worker choice strategy context constructor. @@ -42,7 +42,31 @@ export class WorkerChoiceStrategyContext< private workerChoiceStrategyType: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN ) { this.execute.bind(this) - this.registerWorkerChoiceStrategy(pool, workerChoiceStrategyType) + this.workerChoiceStrategies = new Map< + WorkerChoiceStrategy, + IWorkerChoiceStrategy + >([ + [ + WorkerChoiceStrategies.ROUND_ROBIN, + new RoundRobinWorkerChoiceStrategy(pool) + ], + [ + WorkerChoiceStrategies.LESS_USED, + new LessUsedWorkerChoiceStrategy(pool) + ], + [ + WorkerChoiceStrategies.LESS_BUSY, + new LessBusyWorkerChoiceStrategy(pool) + ], + [ + WorkerChoiceStrategies.FAIR_SHARE, + new FairShareWorkerChoiceStrategy(pool) + ], + [ + WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN, + new WeightedRoundRobinWorkerChoiceStrategy(pool) + ] + ]) } /** @@ -71,7 +95,6 @@ export class WorkerChoiceStrategyContext< this.workerChoiceStrategies.get(workerChoiceStrategy)?.reset() } else { this.workerChoiceStrategyType = workerChoiceStrategy - this.registerWorkerChoiceStrategy(pool, workerChoiceStrategy) } } @@ -107,50 +130,4 @@ export class WorkerChoiceStrategyContext< ) as IWorkerChoiceStrategy ).remove(workerKey) } - - private registerWorkerChoiceStrategy ( - pool: IPoolInternal, - workerChoiceStrategy: WorkerChoiceStrategy - ): void { - if (!this.workerChoiceStrategies.has(workerChoiceStrategy)) { - this.workerChoiceStrategies.set( - workerChoiceStrategy, - this.getWorkerChoiceStrategy(pool, workerChoiceStrategy) - ) - } - } - - /** - * Gets the worker choice strategy instance. - * - * @param pool - The pool instance. - * @param workerChoiceStrategy - The worker choice strategy. - * @returns The worker choice strategy instance. - */ - private getWorkerChoiceStrategy ( - pool: IPoolInternal, - workerChoiceStrategy: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN - ): IWorkerChoiceStrategy { - switch (workerChoiceStrategy) { - case WorkerChoiceStrategies.ROUND_ROBIN: - return new RoundRobinWorkerChoiceStrategy(pool) - case WorkerChoiceStrategies.LESS_USED: - return new LessUsedWorkerChoiceStrategy(pool) - case WorkerChoiceStrategies.LESS_BUSY: - return new LessBusyWorkerChoiceStrategy(pool) - case WorkerChoiceStrategies.FAIR_SHARE: - return new FairShareWorkerChoiceStrategy(pool) - case WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN: - return new WeightedRoundRobinWorkerChoiceStrategy< - Worker, - Data, - Response - >(pool) - default: - throw new Error( - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - `Worker choice strategy '${workerChoiceStrategy}' not found` - ) - } - } } diff --git a/tests/pools/selection-strategies/selection-strategies.test.js b/tests/pools/selection-strategies/selection-strategies.test.js index 254f02de..591b2c4d 100644 --- a/tests/pools/selection-strategies/selection-strategies.test.js +++ b/tests/pools/selection-strategies/selection-strategies.test.js @@ -162,8 +162,8 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( WorkerChoiceStrategies.ROUND_ROBIN - )?.nextWorkerId - ).toBeUndefined() + ).nextWorkerId + ).toBeDefined() pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -180,8 +180,8 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( WorkerChoiceStrategies.ROUND_ROBIN - )?.nextWorkerId - ).toBeUndefined() + ).nextWorkerId + ).toBeDefined() pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -491,8 +491,8 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( WorkerChoiceStrategies.FAIR_SHARE - )?.workerLastVirtualTaskTimestamp - ).toBeUndefined() + ).workerLastVirtualTaskTimestamp + ).toBeDefined() pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE) for (const workerKey of pool.workerChoiceStrategyContext.workerChoiceStrategies .get(WorkerChoiceStrategies.FAIR_SHARE) @@ -517,8 +517,8 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( WorkerChoiceStrategies.FAIR_SHARE - )?.workerLastVirtualTaskTimestamp - ).toBeUndefined() + ).workerLastVirtualTaskTimestamp + ).toBeDefined() pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE) for (const workerKey of pool.workerChoiceStrategyContext.workerChoiceStrategies .get(WorkerChoiceStrategies.FAIR_SHARE) @@ -674,18 +674,18 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN - )?.currentWorkerId - ).toBeUndefined() + ).currentWorkerId + ).toBeDefined() expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN - )?.defaultWorkerWeight - ).toBeUndefined() + ).defaultWorkerWeight + ).toBeDefined() expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN - )?.workersTaskRunTime - ).toBeUndefined() + ).workersTaskRunTime + ).toBeDefined() pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -715,18 +715,18 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN - )?.currentWorkerId - ).toBeUndefined() + ).currentWorkerId + ).toBeDefined() expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN - )?.defaultWorkerWeight - ).toBeUndefined() + ).defaultWorkerWeight + ).toBeDefined() expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN - )?.workersTaskRunTime - ).toBeUndefined() + ).workersTaskRunTime + ).toBeDefined() pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -761,7 +761,7 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy: 'UNKNOWN_STRATEGY' } ) ).toThrowError( - new Error("Worker choice strategy 'UNKNOWN_STRATEGY' not found") + new Error("Invalid worker choice strategy 'UNKNOWN_STRATEGY'") ) }) }) diff --git a/tests/pools/selection-strategies/worker-choice-strategy-context.test.js b/tests/pools/selection-strategies/worker-choice-strategy-context.test.js index 0f02c363..cdefafeb 100644 --- a/tests/pools/selection-strategies/worker-choice-strategy-context.test.js +++ b/tests/pools/selection-strategies/worker-choice-strategy-context.test.js @@ -297,82 +297,4 @@ describe('Worker choice strategy context test suite', () => { WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN ) }) - - it('Verify that getWorkerChoiceStrategy() default return ROUND_ROBIN strategy', () => { - const workerChoiceStrategyContext = new WorkerChoiceStrategyContext( - fixedPool - ) - const strategy = - workerChoiceStrategyContext.getWorkerChoiceStrategy(fixedPool) - expect(strategy).toBeInstanceOf(RoundRobinWorkerChoiceStrategy) - }) - - it('Verify that getWorkerChoiceStrategy() can return ROUND_ROBIN strategy', () => { - const workerChoiceStrategyContext = new WorkerChoiceStrategyContext( - fixedPool - ) - const strategy = workerChoiceStrategyContext.getWorkerChoiceStrategy( - fixedPool, - WorkerChoiceStrategies.ROUND_ROBIN - ) - expect(strategy).toBeInstanceOf(RoundRobinWorkerChoiceStrategy) - }) - - it('Verify that getWorkerChoiceStrategy() can return LESS_USED strategy', () => { - const workerChoiceStrategyContext = new WorkerChoiceStrategyContext( - fixedPool - ) - const strategy = workerChoiceStrategyContext.getWorkerChoiceStrategy( - fixedPool, - WorkerChoiceStrategies.LESS_USED - ) - expect(strategy).toBeInstanceOf(LessUsedWorkerChoiceStrategy) - }) - - it('Verify that getWorkerChoiceStrategy() can return LESS_BUSY strategy', () => { - const workerChoiceStrategyContext = new WorkerChoiceStrategyContext( - fixedPool - ) - const strategy = workerChoiceStrategyContext.getWorkerChoiceStrategy( - fixedPool, - WorkerChoiceStrategies.LESS_BUSY - ) - expect(strategy).toBeInstanceOf(LessBusyWorkerChoiceStrategy) - }) - - it('Verify that getWorkerChoiceStrategy() can return FAIR_SHARE strategy', () => { - const workerChoiceStrategyContext = new WorkerChoiceStrategyContext( - fixedPool - ) - const strategy = workerChoiceStrategyContext.getWorkerChoiceStrategy( - fixedPool, - WorkerChoiceStrategies.FAIR_SHARE - ) - expect(strategy).toBeInstanceOf(FairShareWorkerChoiceStrategy) - }) - - it('Verify that getWorkerChoiceStrategy() can return WEIGHTED_ROUND_ROBIN strategy', () => { - const workerChoiceStrategyContext = new WorkerChoiceStrategyContext( - fixedPool - ) - const strategy = workerChoiceStrategyContext.getWorkerChoiceStrategy( - fixedPool, - WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN - ) - expect(strategy).toBeInstanceOf(WeightedRoundRobinWorkerChoiceStrategy) - }) - - it('Verify that getWorkerChoiceStrategy() throw error on unknown strategy', () => { - const workerChoiceStrategyContext = new WorkerChoiceStrategyContext( - fixedPool - ) - expect(() => { - workerChoiceStrategyContext.getWorkerChoiceStrategy( - fixedPool, - 'UNKNOWN_STRATEGY' - ) - }).toThrowError( - new Error("Worker choice strategy 'UNKNOWN_STRATEGY' not found") - ) - }) }) -- 2.34.1