From 168c526f6e6913506e56f7d5107335c3d3d42938 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sun, 2 Apr 2023 19:59:21 +0200 Subject: [PATCH] feat: add less busy worker choice strategy MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- CHANGELOG.md | 6 +- README.md | 1 + benchmarks/internal/bench.js | 24 ++--- benchmarks/internal/cluster/dynamic.js | 8 +- benchmarks/internal/cluster/fixed.js | 8 +- benchmarks/internal/thread/dynamic.js | 8 +- benchmarks/internal/thread/fixed.js | 8 +- .../less-busy-worker-choice-strategy.ts | 44 +++++++++ .../less-used-worker-choice-strategy.ts | 7 +- .../selection-strategies-types.ts | 4 + .../selection-strategies-utils.ts | 3 + .../selection-strategies-utils.test.js | 11 +++ .../selection-strategies.test.js | 89 ++++++++++++++++++- .../worker-choice-strategy-context.test.js | 30 +++++++ 14 files changed, 216 insertions(+), 35 deletions(-) create mode 100644 src/pools/selection-strategies/less-busy-worker-choice-strategy.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 17e3ff8a..ad3c3cf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add `LESS_BUSY` worker choice strategy. + ### Changed - Optimize worker storage in pool. - Optimize worker alive status check. -- Rename worker choice strategy `LESS_RECENTLY_USED to `LESS_USED` . +- Rename worker choice strategy `LESS_RECENTLY_USED` to `LESS_USED`. - Optimize `LESS_USED` worker choice strategy. ### Fixed diff --git a/README.md b/README.md index a4fab9d8..2adbd97d 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,7 @@ Node versions >= 16.x are supported. - `WorkerChoiceStrategies.ROUND_ROBIN`: Submit tasks to worker in a round robbin fashion - `WorkerChoiceStrategies.LESS_USED`: Submit tasks to the less used worker + - `WorkerChoiceStrategies.LESS_BUSY`: Submit tasks to the less busy worker - `WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN` Submit tasks to worker using a weighted round robin scheduling algorithm based on tasks execution time - `WorkerChoiceStrategies.FAIR_SHARE`: Submit tasks to worker using a fair share tasks scheduling algorithm based on tasks execution time diff --git a/benchmarks/internal/bench.js b/benchmarks/internal/bench.js index e88f40cf..a3de2086 100644 --- a/benchmarks/internal/bench.js +++ b/benchmarks/internal/bench.js @@ -2,25 +2,25 @@ const Benchmark = require('benny') const { dynamicClusterTest, dynamicClusterTestFairShare, - dynamicClusterTestLessRecentlyUsed, + dynamicClusterTestLessUsed, dynamicClusterTestWeightedRoundRobin } = require('./cluster/dynamic') const { fixedClusterTest, fixedClusterTestFairShare, - fixedClusterTestLessRecentlyUsed, + fixedClusterTestLessUsed, fixedClusterTestWeightedRoundRobin } = require('./cluster/fixed') const { dynamicThreadTest, dynamicThreadTestFairShare, - dynamicThreadTestLessRecentlyUsed, + dynamicThreadTestLessUsed, dynamicThreadTestWeightedRoundRobin } = require('./thread/dynamic') const { fixedThreadTest, fixedThreadTestFairShare, - fixedThreadTestLessRecentlyUsed, + fixedThreadTestLessUsed, fixedThreadTestWeightedRoundRobin } = require('./thread/fixed') @@ -32,8 +32,8 @@ Benchmark.suite( Benchmark.add('Poolifier:Fixed:ThreadPool', async () => { await fixedThreadTest() }), - Benchmark.add('Poolifier:Fixed:ThreadPool:LessRecentlyUsed', async () => { - await fixedThreadTestLessRecentlyUsed() + Benchmark.add('Poolifier:Fixed:ThreadPool:LessUsed', async () => { + await fixedThreadTestLessUsed() }), Benchmark.add('Poolifier:Fixed:ThreadPool:WeightedRoundRobin', async () => { await fixedThreadTestWeightedRoundRobin() @@ -44,8 +44,8 @@ Benchmark.suite( Benchmark.add('Poolifier:Dynamic:ThreadPool', async () => { await dynamicThreadTest() }), - Benchmark.add('Poolifier:Dynamic:ThreadPool:LessRecentlyUsed', async () => { - await dynamicThreadTestLessRecentlyUsed() + Benchmark.add('Poolifier:Dynamic:ThreadPool:LessUsed', async () => { + await dynamicThreadTestLessUsed() }), Benchmark.add('Poolifier:Dynamic:ThreadPool:WeightedRoundRobin', async () => { await dynamicThreadTestWeightedRoundRobin() @@ -56,8 +56,8 @@ Benchmark.suite( Benchmark.add('Poolifier:Fixed:ClusterPool', async () => { await fixedClusterTest() }), - Benchmark.add('Poolifier:Fixed:ClusterPool:LessRecentlyUsed', async () => { - await fixedClusterTestLessRecentlyUsed() + Benchmark.add('Poolifier:Fixed:ClusterPool:LessUsed', async () => { + await fixedClusterTestLessUsed() }), Benchmark.add('Poolifier:Fixed:ClusterPool:WeightedRoundRobin', async () => { await fixedClusterTestWeightedRoundRobin @@ -68,8 +68,8 @@ Benchmark.suite( Benchmark.add('Poolifier:Dynamic:ClusterPool', async () => { await dynamicClusterTest() }), - Benchmark.add('Poolifier:Dynamic:ClusterPool:LessRecentlyUsed', async () => { - await dynamicClusterTestLessRecentlyUsed() + Benchmark.add('Poolifier:Dynamic:ClusterPool:LessUsed', async () => { + await dynamicClusterTestLessUsed() }), Benchmark.add( 'Poolifier:Dynamic:ClusterPool:WeightedRoundRobin', diff --git a/benchmarks/internal/cluster/dynamic.js b/benchmarks/internal/cluster/dynamic.js index 43fa0485..60ee14f6 100644 --- a/benchmarks/internal/cluster/dynamic.js +++ b/benchmarks/internal/cluster/dynamic.js @@ -13,7 +13,7 @@ const dynamicPool = new DynamicClusterPool( './benchmarks/internal/cluster/worker.js' ) -const dynamicPoolLessRecentlyUsed = new DynamicClusterPool( +const dynamicPoolLessUsed = new DynamicClusterPool( size / 2, size * 3, './benchmarks/internal/cluster/worker.js', @@ -40,10 +40,10 @@ async function dynamicClusterTest ( return runPoolifierTest(dynamicPool, { tasks, workerData }) } -async function dynamicClusterTestLessRecentlyUsed ( +async function dynamicClusterTestLessUsed ( { tasks, workerData } = { tasks: numberOfTasks, workerData: { proof: 'ok' } } ) { - return runPoolifierTest(dynamicPoolLessRecentlyUsed, { tasks, workerData }) + return runPoolifierTest(dynamicPoolLessUsed, { tasks, workerData }) } async function dynamicClusterTestWeightedRoundRobin ( @@ -60,7 +60,7 @@ async function dynamicClusterTestFairShare ( module.exports = { dynamicClusterTest, - dynamicClusterTestLessRecentlyUsed, + dynamicClusterTestLessUsed, dynamicClusterTestWeightedRoundRobin, dynamicClusterTestFairShare } diff --git a/benchmarks/internal/cluster/fixed.js b/benchmarks/internal/cluster/fixed.js index 211db608..69e4a148 100644 --- a/benchmarks/internal/cluster/fixed.js +++ b/benchmarks/internal/cluster/fixed.js @@ -12,7 +12,7 @@ const fixedPool = new FixedClusterPool( './benchmarks/internal/cluster/worker.js' ) -const fixedPoolLessRecentlyUsed = new FixedClusterPool( +const fixedPoolLessUsed = new FixedClusterPool( size, './benchmarks/internal/cluster/worker.js', { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED } @@ -36,10 +36,10 @@ async function fixedClusterTest ( return runPoolifierTest(fixedPool, { tasks, workerData }) } -async function fixedClusterTestLessRecentlyUsed ( +async function fixedClusterTestLessUsed ( { tasks, workerData } = { tasks: numberOfTasks, workerData: { proof: 'ok' } } ) { - return runPoolifierTest(fixedPoolLessRecentlyUsed, { tasks, workerData }) + return runPoolifierTest(fixedPoolLessUsed, { tasks, workerData }) } async function fixedClusterTestWeightedRoundRobin ( @@ -56,7 +56,7 @@ async function fixedClusterTestFairShare ( module.exports = { fixedClusterTest, - fixedClusterTestLessRecentlyUsed, + fixedClusterTestLessUsed, fixedClusterTestWeightedRoundRobin, fixedClusterTestFairShare } diff --git a/benchmarks/internal/thread/dynamic.js b/benchmarks/internal/thread/dynamic.js index 79d47215..04f18406 100644 --- a/benchmarks/internal/thread/dynamic.js +++ b/benchmarks/internal/thread/dynamic.js @@ -13,7 +13,7 @@ const dynamicPool = new DynamicThreadPool( './benchmarks/internal/thread/worker.js' ) -const dynamicPoolLessRecentlyUsed = new DynamicThreadPool( +const dynamicPoolLessUsed = new DynamicThreadPool( size / 2, size * 3, './benchmarks/internal/thread/worker.js', @@ -40,10 +40,10 @@ async function dynamicThreadTest ( return runPoolifierTest(dynamicPool, { tasks, workerData }) } -async function dynamicThreadTestLessRecentlyUsed ( +async function dynamicThreadTestLessUsed ( { tasks, workerData } = { tasks: numberOfTasks, workerData: { proof: 'ok' } } ) { - return runPoolifierTest(dynamicPoolLessRecentlyUsed, { tasks, workerData }) + return runPoolifierTest(dynamicPoolLessUsed, { tasks, workerData }) } async function dynamicThreadTestWeightedRoundRobin ( @@ -60,7 +60,7 @@ async function dynamicThreadTestFairShare ( module.exports = { dynamicThreadTest, - dynamicThreadTestLessRecentlyUsed, + dynamicThreadTestLessUsed, dynamicThreadTestWeightedRoundRobin, dynamicThreadTestFairShare } diff --git a/benchmarks/internal/thread/fixed.js b/benchmarks/internal/thread/fixed.js index 2d6ee355..ee4105be 100644 --- a/benchmarks/internal/thread/fixed.js +++ b/benchmarks/internal/thread/fixed.js @@ -12,7 +12,7 @@ const fixedPool = new FixedThreadPool( './benchmarks/internal/thread/worker.js' ) -const fixedPoolLessRecentlyUsed = new FixedThreadPool( +const fixedPoolLessUsed = new FixedThreadPool( size, './benchmarks/internal/thread/worker.js', { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED } @@ -36,10 +36,10 @@ async function fixedThreadTest ( return runPoolifierTest(fixedPool, { tasks, workerData }) } -async function fixedThreadTestLessRecentlyUsed ( +async function fixedThreadTestLessUsed ( { tasks, workerData } = { tasks: numberOfTasks, workerData: { proof: 'ok' } } ) { - return runPoolifierTest(fixedPoolLessRecentlyUsed, { tasks, workerData }) + return runPoolifierTest(fixedPoolLessUsed, { tasks, workerData }) } async function fixedThreadTestWeightedRoundRobin ( @@ -56,7 +56,7 @@ async function fixedThreadTestFairShare ( module.exports = { fixedThreadTest, - fixedThreadTestLessRecentlyUsed, + fixedThreadTestLessUsed, fixedThreadTestWeightedRoundRobin, fixedThreadTestFairShare } diff --git a/src/pools/selection-strategies/less-busy-worker-choice-strategy.ts b/src/pools/selection-strategies/less-busy-worker-choice-strategy.ts new file mode 100644 index 00000000..769f3fb6 --- /dev/null +++ b/src/pools/selection-strategies/less-busy-worker-choice-strategy.ts @@ -0,0 +1,44 @@ +import type { IPoolWorker } from '../pool-worker' +import { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy' +import type { RequiredStatistics } from './selection-strategies-types' + +/** + * Selects the less busy worker. + * + * @typeParam Worker - Type of worker which manages the strategy. + * @typeParam Data - Type of data sent to the worker. This can only be serializable data. + * @typeParam Response - Type of response of execution. This can only be serializable data. + */ +export class LessBusyWorkerChoiceStrategy< + Worker extends IPoolWorker, + Data, + Response +> extends AbstractWorkerChoiceStrategy { + /** {@inheritDoc} */ + public readonly requiredStatistics: RequiredStatistics = { + runTime: true + } + + /** {@inheritDoc} */ + public reset (): boolean { + return true + } + + /** {@inheritDoc} */ + public choose (): Worker { + let minRunTime = Infinity + let lessBusyWorker!: Worker + for (const value of this.pool.workers.values()) { + const worker = value.worker + const workerRunTime = this.pool.getWorkerTasksUsage(worker) + ?.runTime as number + if (!this.isDynamicPool && workerRunTime === 0) { + return worker + } else if (workerRunTime < minRunTime) { + minRunTime = workerRunTime + lessBusyWorker = worker + } + } + return lessBusyWorker + } +} diff --git a/src/pools/selection-strategies/less-used-worker-choice-strategy.ts b/src/pools/selection-strategies/less-used-worker-choice-strategy.ts index f220b2c8..61c8fb20 100644 --- a/src/pools/selection-strategies/less-used-worker-choice-strategy.ts +++ b/src/pools/selection-strategies/less-used-worker-choice-strategy.ts @@ -21,8 +21,7 @@ export class LessUsedWorkerChoiceStrategy< /** {@inheritDoc} */ public choose (): Worker { let minNumberOfTasks = Infinity - // A worker is always found because it picks the one with fewer tasks - let lessRecentlyUsedWorker!: Worker + let lessUsedWorker!: Worker for (const value of this.pool.workers.values()) { const worker = value.worker const tasksUsage = this.pool.getWorkerTasksUsage(worker) @@ -32,9 +31,9 @@ export class LessUsedWorkerChoiceStrategy< return worker } else if (workerTasks < minNumberOfTasks) { minNumberOfTasks = workerTasks - lessRecentlyUsedWorker = worker + lessUsedWorker = worker } } - return lessRecentlyUsedWorker + return lessUsedWorker } } diff --git a/src/pools/selection-strategies/selection-strategies-types.ts b/src/pools/selection-strategies/selection-strategies-types.ts index 23efd299..9ae66765 100644 --- a/src/pools/selection-strategies/selection-strategies-types.ts +++ b/src/pools/selection-strategies/selection-strategies-types.ts @@ -12,6 +12,10 @@ export const WorkerChoiceStrategies = Object.freeze({ * Less used worker selection strategy. */ LESS_USED: 'LESS_USED', + /** + * Less busy worker selection strategy. + */ + LESS_BUSY: 'LESS_BUSY', /** * Fair share worker selection strategy. */ diff --git a/src/pools/selection-strategies/selection-strategies-utils.ts b/src/pools/selection-strategies/selection-strategies-utils.ts index 75848544..1330ec19 100644 --- a/src/pools/selection-strategies/selection-strategies-utils.ts +++ b/src/pools/selection-strategies/selection-strategies-utils.ts @@ -1,6 +1,7 @@ import type { IPoolInternal } from '../pool-internal' import type { IPoolWorker } from '../pool-worker' import { FairShareWorkerChoiceStrategy } from './fair-share-worker-choice-strategy' +import { LessBusyWorkerChoiceStrategy } from './less-busy-worker-choice-strategy' import { LessUsedWorkerChoiceStrategy } from './less-used-worker-choice-strategy' import { RoundRobinWorkerChoiceStrategy } from './round-robin-worker-choice-strategy' import type { @@ -30,6 +31,8 @@ export function getWorkerChoiceStrategy< 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: diff --git a/tests/pools/selection-strategies/selection-strategies-utils.test.js b/tests/pools/selection-strategies/selection-strategies-utils.test.js index 43496040..87150745 100644 --- a/tests/pools/selection-strategies/selection-strategies-utils.test.js +++ b/tests/pools/selection-strategies/selection-strategies-utils.test.js @@ -13,6 +13,9 @@ const { const { LessUsedWorkerChoiceStrategy } = require('../../../lib/pools/selection-strategies/less-used-worker-choice-strategy') +const { + LessBusyWorkerChoiceStrategy +} = require('../../../lib/pools/selection-strategies/less-busy-worker-choice-strategy') const { FairShareWorkerChoiceStrategy } = require('../../../lib/pools/selection-strategies/fair-share-worker-choice-strategy') @@ -57,6 +60,14 @@ describe('Selection strategies utils test suite', () => { expect(strategy).toBeInstanceOf(LessUsedWorkerChoiceStrategy) }) + it('Verify that getWorkerChoiceStrategy() can return LESS_BUSY strategy', () => { + const strategy = getWorkerChoiceStrategy( + pool, + WorkerChoiceStrategies.LESS_BUSY + ) + expect(strategy).toBeInstanceOf(LessBusyWorkerChoiceStrategy) + }) + it('Verify that getWorkerChoiceStrategy() can return FAIR_SHARE strategy', () => { const strategy = getWorkerChoiceStrategy( pool, diff --git a/tests/pools/selection-strategies/selection-strategies.test.js b/tests/pools/selection-strategies/selection-strategies.test.js index 22641947..ac3e2720 100644 --- a/tests/pools/selection-strategies/selection-strategies.test.js +++ b/tests/pools/selection-strategies/selection-strategies.test.js @@ -13,6 +13,7 @@ describe('Selection strategies test suite', () => { it('Verify that WorkerChoiceStrategies enumeration provides string values', () => { expect(WorkerChoiceStrategies.ROUND_ROBIN).toBe('ROUND_ROBIN') expect(WorkerChoiceStrategies.LESS_USED).toBe('LESS_USED') + expect(WorkerChoiceStrategies.LESS_BUSY).toBe('LESS_BUSY') expect(WorkerChoiceStrategies.FAIR_SHARE).toBe('FAIR_SHARE') expect(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN).toBe( 'WEIGHTED_ROUND_ROBIN' @@ -236,7 +237,7 @@ describe('Selection strategies test suite', () => { './tests/worker-files/thread/testWorker.js', { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED } ) - // TODO: Create a better test to cover `LessRecentlyUsedWorkerChoiceStrategy#choose` + // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose` const promises = [] for (let i = 0; i < max * 2; i++) { promises.push(pool.execute()) @@ -253,7 +254,91 @@ describe('Selection strategies test suite', () => { './tests/worker-files/thread/testWorker.js', { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED } ) - // TODO: Create a better test to cover `LessRecentlyUsedWorkerChoiceStrategy#choose` + // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose` + const promises = [] + for (let i = 0; i < max * 2; i++) { + promises.push(pool.execute()) + } + await Promise.all(promises) + // We need to clean up the resources after our test + await pool.destroy() + }) + + it('Verify LESS_BUSY strategy is taken at pool creation', async () => { + const pool = new FixedThreadPool( + max, + './tests/worker-files/thread/testWorker.js', + { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY } + ) + expect(pool.opts.workerChoiceStrategy).toBe( + WorkerChoiceStrategies.LESS_BUSY + ) + // We need to clean up the resources after our test + await pool.destroy() + }) + + it('Verify LESS_BUSY strategy can be set after pool creation', async () => { + const pool = new FixedThreadPool( + max, + './tests/worker-files/thread/testWorker.js' + ) + pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_BUSY) + expect(pool.opts.workerChoiceStrategy).toBe( + WorkerChoiceStrategies.LESS_BUSY + ) + // We need to clean up the resources after our test + await pool.destroy() + }) + + it('Verify LESS_BUSY strategy default tasks usage statistics requirements', async () => { + let pool = new FixedThreadPool( + max, + './tests/worker-files/thread/testWorker.js' + ) + pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_BUSY) + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .requiredStatistics.runTime + ).toBe(true) + await pool.destroy() + pool = new DynamicThreadPool( + min, + max, + './tests/worker-files/thread/testWorker.js' + ) + pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_BUSY) + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .requiredStatistics.runTime + ).toBe(true) + // We need to clean up the resources after our test + await pool.destroy() + }) + + it('Verify LESS_BUSY strategy can be run in a fixed pool', async () => { + const pool = new FixedThreadPool( + max, + './tests/worker-files/thread/testWorker.js', + { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY } + ) + // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose` + const promises = [] + for (let i = 0; i < max * 2; i++) { + promises.push(pool.execute()) + } + await Promise.all(promises) + // We need to clean up the resources after our test + await pool.destroy() + }) + + it('Verify LESS_BUSY strategy can be run in a dynamic pool', async () => { + const pool = new DynamicThreadPool( + min, + max, + './tests/worker-files/thread/testWorker.js', + { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY } + ) + // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose` const promises = [] for (let i = 0; i < max * 2; i++) { promises.push(pool.execute()) 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 0079e728..9380a038 100644 --- a/tests/pools/selection-strategies/worker-choice-strategy-context.test.js +++ b/tests/pools/selection-strategies/worker-choice-strategy-context.test.js @@ -14,6 +14,9 @@ const { const { LessUsedWorkerChoiceStrategy } = require('../../../lib/pools/selection-strategies/less-used-worker-choice-strategy') +const { + LessBusyWorkerChoiceStrategy +} = require('../../../lib/pools/selection-strategies/less-busy-worker-choice-strategy') const { FairShareWorkerChoiceStrategy } = require('../../../lib/pools/selection-strategies/fair-share-worker-choice-strategy') @@ -140,6 +143,33 @@ describe('Worker choice strategy context test suite', () => { ).toBeInstanceOf(LessUsedWorkerChoiceStrategy) }) + it('Verify that setWorkerChoiceStrategy() works with LESS_BUSY and fixed pool', () => { + const workerChoiceStrategyContext = new WorkerChoiceStrategyContext( + fixedPool + ) + workerChoiceStrategyContext.setWorkerChoiceStrategy( + WorkerChoiceStrategies.LESS_BUSY + ) + expect( + workerChoiceStrategyContext.getWorkerChoiceStrategy() + ).toBeInstanceOf(LessBusyWorkerChoiceStrategy) + }) + + it('Verify that setWorkerChoiceStrategy() works with LESS_BUSY and dynamic pool', () => { + const workerChoiceStrategyContext = new WorkerChoiceStrategyContext( + dynamicPool + ) + workerChoiceStrategyContext.setWorkerChoiceStrategy( + WorkerChoiceStrategies.LESS_BUSY + ) + expect( + workerChoiceStrategyContext.getWorkerChoiceStrategy() + ).toBeInstanceOf(DynamicPoolWorkerChoiceStrategy) + expect( + workerChoiceStrategyContext.getWorkerChoiceStrategy().workerChoiceStrategy + ).toBeInstanceOf(LessBusyWorkerChoiceStrategy) + }) + it('Verify that setWorkerChoiceStrategy() works with FAIR_SHARE and fixed pool', () => { const workerChoiceStrategyContext = new WorkerChoiceStrategyContext( fixedPool -- 2.34.1