From a20f0ba5aa9c6946254aa197286ad9b70b6a0319 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sat, 15 Apr 2023 13:36:34 +0200 Subject: [PATCH] feat: add pool runtime setters MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- CHANGELOG.md | 10 +++ package.json | 2 +- pnpm-lock.yaml | 38 ++++---- src/pools/abstract-pool.ts | 72 +++++++++++++--- src/pools/pool.ts | 24 +++++- .../abstract-worker-choice-strategy.ts | 12 ++- .../fair-share-worker-choice-strategy.ts | 2 +- .../less-busy-worker-choice-strategy.ts | 2 +- .../less-used-worker-choice-strategy.ts | 2 +- .../round-robin-worker-choice-strategy.ts | 2 +- .../selection-strategies-types.ts | 6 ++ ...hted-round-robin-worker-choice-strategy.ts | 2 +- .../worker-choice-strategy-context.ts | 11 +++ tests/pools/abstract/abstract-pool.test.js | 86 ++++++++++++++++++- .../selection-strategies.test.js | 24 ++++-- 15 files changed, 245 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d599b16..381fa711 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add tasks queue enablement runtime setter to pool. +- Add tasks queue options runtime setter to pool. +- Add worker choice strategy options runtime setter to pool. + +### Changed + +- Remove the tasks queuing experimental status. + ### Fixed - Fix worker function type definition and validation. diff --git a/package.json b/package.json index a2812dcd..ef5ef856 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "eslint": "^8.38.0", "eslint-config-standard": "^17.0.0", "eslint-config-standard-with-typescript": "^34.0.1", - "eslint-define-config": "^1.17.0", + "eslint-define-config": "^1.18.0", "eslint-import-resolver-typescript": "^3.5.5", "eslint-plugin-import": "^2.27.5", "eslint-plugin-jsdoc": "^41.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 229d36d0..3f111a26 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,8 +44,8 @@ devDependencies: specifier: ^34.0.1 version: 34.0.1(@typescript-eslint/eslint-plugin@5.58.0)(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.38.0)(typescript@5.0.4) eslint-define-config: - specifier: ^1.17.0 - version: 1.17.0 + specifier: ^1.18.0 + version: 1.18.0 eslint-import-resolver-typescript: specifier: ^3.5.5 version: 3.5.5(@typescript-eslint/parser@5.58.0)(eslint-plugin-import@2.27.5)(eslint@8.38.0) @@ -748,7 +748,7 @@ packages: optional: true dependencies: '@rollup/pluginutils': 5.0.2(rollup@3.20.2) - resolve: 1.22.2 + resolve: 1.22.3 rollup: 3.20.2 typescript: 5.0.4 dev: true @@ -1622,8 +1622,8 @@ packages: resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} dev: true - /commander@10.0.0: - resolution: {integrity: sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA==} + /commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} dev: true @@ -2203,8 +2203,8 @@ packages: eslint-plugin-promise: 6.1.1(eslint@8.38.0) dev: true - /eslint-define-config@1.17.0: - resolution: {integrity: sha512-J1sweMoWsLcokaiAlfOCC4yMoHbvC/kDAxorm5TkUcD74w+kauMIyjKLM3dOadNxVKOjDiYN1Tu2x9N+4EUuuQ==} + /eslint-define-config@1.18.0: + resolution: {integrity: sha512-8qWT7aNU5M0W+WfoUixVaR79sqt3b280CK4bNPCkqXlTWUOYlEy3yEcXZFduvWawkNjuYWpZ2UjcBfvfnvGpvA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0, npm: '>=6.14.13', pnpm: '>= 7.0.0'} dev: true @@ -2213,7 +2213,7 @@ packages: dependencies: debug: 3.2.7 is-core-module: 2.12.0 - resolve: 1.22.2 + resolve: 1.22.3 transitivePeerDependencies: - supports-color dev: true @@ -2228,7 +2228,7 @@ packages: debug: 4.3.4(supports-color@8.1.1) enhanced-resolve: 5.12.0 eslint: 8.38.0 - eslint-module-utils: 2.7.4(@typescript-eslint/parser@5.58.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.38.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.58.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.38.0) eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.58.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.38.0) get-tsconfig: 4.5.0 globby: 13.1.4 @@ -2242,8 +2242,8 @@ packages: - supports-color dev: true - /eslint-module-utils@2.7.4(@typescript-eslint/parser@5.58.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.38.0): - resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} + /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.58.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.38.0): + resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -2301,13 +2301,13 @@ packages: doctrine: 2.1.0 eslint: 8.38.0 eslint-import-resolver-node: 0.3.7 - eslint-module-utils: 2.7.4(@typescript-eslint/parser@5.58.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.38.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.58.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.38.0) has: 1.0.3 is-core-module: 2.12.0 is-glob: 4.0.3 minimatch: 3.1.2 object.values: 1.1.6 - resolve: 1.22.2 + resolve: 1.22.3 semver: 6.3.0 tsconfig-paths: 3.14.2 transitivePeerDependencies: @@ -2348,7 +2348,7 @@ packages: ignore: 5.2.4 is-core-module: 2.12.0 minimatch: 3.1.2 - resolve: 1.22.2 + resolve: 1.22.3 semver: 7.4.0 dev: true @@ -3823,7 +3823,7 @@ packages: dependencies: chalk: 5.2.0 cli-truncate: 3.1.0 - commander: 10.0.0 + commander: 10.0.1 debug: 4.3.4(supports-color@8.1.1) execa: 7.1.1 lilconfig: 2.1.0 @@ -4335,7 +4335,7 @@ packages: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: hosted-git-info: 2.8.9 - resolve: 1.22.2 + resolve: 1.22.3 semver: 5.7.1 validate-npm-package-license: 3.0.4 dev: true @@ -4962,7 +4962,7 @@ packages: resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} engines: {node: '>= 0.10'} dependencies: - resolve: 1.22.2 + resolve: 1.22.3 dev: true /redent@3.0.0: @@ -5076,8 +5076,8 @@ packages: path-parse: 1.0.7 dev: true - /resolve@1.22.2: - resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} + /resolve@1.22.3: + resolution: {integrity: sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==} hasBin: true dependencies: is-core-module: 2.12.0 diff --git a/src/pools/abstract-pool.ts b/src/pools/abstract-pool.ts index 3be40e6d..f1c6ad13 100644 --- a/src/pools/abstract-pool.ts +++ b/src/pools/abstract-pool.ts @@ -17,7 +17,8 @@ import { PoolEmitter } from './pool' import type { IWorker, Task, TasksUsage, WorkerNode } from './worker' import { WorkerChoiceStrategies, - type WorkerChoiceStrategy + type WorkerChoiceStrategy, + type WorkerChoiceStrategyOptions } from './selection-strategies/selection-strategies-types' import { WorkerChoiceStrategyContext } from './selection-strategies/worker-choice-strategy-context' import { CircularArray } from '../circular-array' @@ -144,16 +145,12 @@ export abstract class AbstractPool< this.opts.enableEvents = opts.enableEvents ?? true this.opts.enableTasksQueue = opts.enableTasksQueue ?? false if (this.opts.enableTasksQueue) { - if ((opts.tasksQueueOptions?.concurrency as number) <= 0) { - throw new Error( - `Invalid worker tasks concurrency '${ - (opts.tasksQueueOptions as TasksQueueOptions).concurrency as number - }'` - ) - } - this.opts.tasksQueueOptions = { - concurrency: opts.tasksQueueOptions?.concurrency ?? 1 - } + this.checkValidTasksQueueOptions( + opts.tasksQueueOptions as TasksQueueOptions + ) + this.opts.tasksQueueOptions = this.buildTasksQueueOptions( + opts.tasksQueueOptions as TasksQueueOptions + ) } } @@ -167,6 +164,18 @@ export abstract class AbstractPool< } } + private checkValidTasksQueueOptions ( + tasksQueueOptions: TasksQueueOptions + ): void { + if ((tasksQueueOptions?.concurrency as number) <= 0) { + throw new Error( + `Invalid worker tasks concurrency '${ + tasksQueueOptions.concurrency as number + }'` + ) + } + } + /** @inheritDoc */ public abstract get type (): PoolType @@ -223,10 +232,49 @@ export abstract class AbstractPool< }) } this.workerChoiceStrategyContext.setWorkerChoiceStrategy( - workerChoiceStrategy + this.opts.workerChoiceStrategy + ) + } + + /** @inheritDoc */ + public setWorkerChoiceStrategyOptions ( + workerChoiceStrategyOptions: WorkerChoiceStrategyOptions + ): void { + this.opts.workerChoiceStrategyOptions = workerChoiceStrategyOptions + this.workerChoiceStrategyContext.setOptions( + this.opts.workerChoiceStrategyOptions ) } + /** @inheritDoc */ + public enableTasksQueue (enable: boolean, opts?: TasksQueueOptions): void { + if (this.opts.enableTasksQueue === true && !enable) { + for (const [workerNodeKey] of this.workerNodes.entries()) { + this.flushTasksQueue(workerNodeKey) + } + } + this.opts.enableTasksQueue = enable + this.setTasksQueueOptions(opts as TasksQueueOptions) + } + + /** @inheritDoc */ + public setTasksQueueOptions (opts: TasksQueueOptions): void { + if (this.opts.enableTasksQueue === true) { + this.checkValidTasksQueueOptions(opts) + this.opts.tasksQueueOptions = this.buildTasksQueueOptions(opts) + } else { + delete this.opts.tasksQueueOptions + } + } + + private buildTasksQueueOptions ( + tasksQueueOptions: TasksQueueOptions + ): TasksQueueOptions { + return { + concurrency: tasksQueueOptions?.concurrency ?? 1 + } + } + /** * Whether the pool is full or not. * diff --git a/src/pools/pool.ts b/src/pools/pool.ts index 83e01eb7..ea60833a 100644 --- a/src/pools/pool.ts +++ b/src/pools/pool.ts @@ -98,14 +98,11 @@ export interface PoolOptions { /** * Pool worker tasks queue. * - * @experimental * @defaultValue false */ enableTasksQueue?: boolean /** * Pool worker tasks queue options. - * - * @experimental */ tasksQueueOptions?: TasksQueueOptions } @@ -168,4 +165,25 @@ export interface IPool< * @param workerChoiceStrategy - The worker choice strategy. */ setWorkerChoiceStrategy: (workerChoiceStrategy: WorkerChoiceStrategy) => void + /** + * Sets the worker choice strategy options in this pool. + * + * @param workerChoiceStrategyOptions - The worker choice strategy options. + */ + setWorkerChoiceStrategyOptions: ( + workerChoiceStrategyOptions: WorkerChoiceStrategyOptions + ) => void + /** + * Enables/disables the worker tasks queue in this pool. + * + * @param enable - Whether to enable or disable the worker tasks queue. + * @param tasksQueueOptions - The worker tasks queue options. + */ + enableTasksQueue: (enable: boolean, opts?: TasksQueueOptions) => void + /** + * Sets the worker tasks queue options in this pool. + * + * @param tasksQueueOptions - The worker tasks queue options. + */ + setTasksQueueOptions: (tasksQueueOptions: TasksQueueOptions) => void } diff --git a/src/pools/selection-strategies/abstract-worker-choice-strategy.ts b/src/pools/selection-strategies/abstract-worker-choice-strategy.ts index 77b44f6e..859ead82 100644 --- a/src/pools/selection-strategies/abstract-worker-choice-strategy.ts +++ b/src/pools/selection-strategies/abstract-worker-choice-strategy.ts @@ -36,7 +36,7 @@ export abstract class AbstractWorkerChoiceStrategy< */ public constructor ( protected readonly pool: IPool, - protected readonly opts: WorkerChoiceStrategyOptions = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS + protected opts: WorkerChoiceStrategyOptions = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS ) { this.isDynamicPool = this.pool.type === PoolType.DYNAMIC this.choose.bind(this) @@ -47,6 +47,10 @@ export abstract class AbstractWorkerChoiceStrategy< this.requiredStatistics.avgRunTime = false this.requiredStatistics.medRunTime = opts.medRunTime as boolean } + if (this.requiredStatistics.medRunTime && opts.medRunTime === false) { + this.requiredStatistics.avgRunTime = true + this.requiredStatistics.medRunTime = opts.medRunTime as boolean + } } /** @inheritDoc */ @@ -57,4 +61,10 @@ export abstract class AbstractWorkerChoiceStrategy< /** @inheritDoc */ public abstract remove (workerNodeKey: number): boolean + + /** @inheritDoc */ + public setOptions (opts: WorkerChoiceStrategyOptions): void { + this.checkOptions(opts) + this.opts = opts + } } 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 81944f7a..4d6ef2a8 100644 --- a/src/pools/selection-strategies/fair-share-worker-choice-strategy.ts +++ b/src/pools/selection-strategies/fair-share-worker-choice-strategy.ts @@ -52,7 +52,7 @@ export class FairShareWorkerChoiceStrategy< opts: WorkerChoiceStrategyOptions = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS ) { super(pool, opts) - this.checkOptions(opts) + this.checkOptions(this.opts) } /** @inheritDoc */ diff --git a/src/pools/selection-strategies/less-busy-worker-choice-strategy.ts b/src/pools/selection-strategies/less-busy-worker-choice-strategy.ts index 708c491f..d862405c 100644 --- a/src/pools/selection-strategies/less-busy-worker-choice-strategy.ts +++ b/src/pools/selection-strategies/less-busy-worker-choice-strategy.ts @@ -35,7 +35,7 @@ export class LessBusyWorkerChoiceStrategy< opts: WorkerChoiceStrategyOptions = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS ) { super(pool, opts) - this.checkOptions(opts) + this.checkOptions(this.opts) } /** @inheritDoc */ 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 1138df95..51039c95 100644 --- a/src/pools/selection-strategies/less-used-worker-choice-strategy.ts +++ b/src/pools/selection-strategies/less-used-worker-choice-strategy.ts @@ -27,7 +27,7 @@ export class LessUsedWorkerChoiceStrategy< opts: WorkerChoiceStrategyOptions = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS ) { super(pool, opts) - this.checkOptions(opts) + this.checkOptions(this.opts) } /** @inheritDoc */ diff --git a/src/pools/selection-strategies/round-robin-worker-choice-strategy.ts b/src/pools/selection-strategies/round-robin-worker-choice-strategy.ts index 107e9639..d2d6f6d6 100644 --- a/src/pools/selection-strategies/round-robin-worker-choice-strategy.ts +++ b/src/pools/selection-strategies/round-robin-worker-choice-strategy.ts @@ -32,7 +32,7 @@ export class RoundRobinWorkerChoiceStrategy< opts: WorkerChoiceStrategyOptions = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS ) { super(pool, opts) - this.checkOptions(opts) + this.checkOptions(this.opts) } /** @inheritDoc */ diff --git a/src/pools/selection-strategies/selection-strategies-types.ts b/src/pools/selection-strategies/selection-strategies-types.ts index 065b310f..f9a50435 100644 --- a/src/pools/selection-strategies/selection-strategies-types.ts +++ b/src/pools/selection-strategies/selection-strategies-types.ts @@ -81,4 +81,10 @@ export interface IWorkerChoiceStrategy { * @param workerNodeKey - The worker node key. */ remove: (workerNodeKey: number) => boolean + /** + * Sets the worker choice strategy options. + * + * @param opts - The worker choice strategy options. + */ + setOptions: (opts: WorkerChoiceStrategyOptions) => void } 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 dc2e5df3..c5c20437 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 @@ -61,7 +61,7 @@ export class WeightedRoundRobinWorkerChoiceStrategy< opts: WorkerChoiceStrategyOptions = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS ) { super(pool, opts) - this.checkOptions(opts) + this.checkOptions(this.opts) this.defaultWorkerWeight = this.computeWorkerWeight() this.initWorkersTaskRunTime() } diff --git a/src/pools/selection-strategies/worker-choice-strategy-context.ts b/src/pools/selection-strategies/worker-choice-strategy-context.ts index b075c4ea..5e9f7de9 100644 --- a/src/pools/selection-strategies/worker-choice-strategy-context.ts +++ b/src/pools/selection-strategies/worker-choice-strategy-context.ts @@ -127,4 +127,15 @@ export class WorkerChoiceStrategyContext< ) as IWorkerChoiceStrategy ).remove(workerNodeKey) } + + /** + * Sets the worker choice strategies in the context options. + * + * @param opts - The worker choice strategy options. + */ + public setOptions (opts: WorkerChoiceStrategyOptions): void { + this.workerChoiceStrategies.forEach(workerChoiceStrategy => { + workerChoiceStrategy.setOptions(opts) + }) + } } diff --git a/tests/pools/abstract/abstract-pool.test.js b/tests/pools/abstract/abstract-pool.test.js index 86506f67..54f9382a 100644 --- a/tests/pools/abstract/abstract-pool.test.js +++ b/tests/pools/abstract/abstract-pool.test.js @@ -131,7 +131,7 @@ describe('Abstract pool test suite', () => { await pool.destroy() }) - it('Verify that pool options are valid', async () => { + it('Verify that pool options are validated', async () => { expect( () => new FixedThreadPool( @@ -155,6 +155,90 @@ describe('Abstract pool test suite', () => { ).toThrowError("Invalid worker choice strategy 'invalidStrategy'") }) + it('Verify that worker choice strategy options can be set', async () => { + const pool = new FixedThreadPool( + numberOfWorkers, + './tests/worker-files/thread/testWorker.js', + { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE } + ) + expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({ + medRunTime: false + }) + for (const [, workerChoiceStrategy] of pool.workerChoiceStrategyContext + .workerChoiceStrategies) { + expect(workerChoiceStrategy.opts).toStrictEqual({ medRunTime: false }) + } + expect( + pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime + ).toBe(true) + expect( + pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime + ).toBe(false) + pool.setWorkerChoiceStrategyOptions({ medRunTime: true }) + expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({ + medRunTime: true + }) + for (const [, workerChoiceStrategy] of pool.workerChoiceStrategyContext + .workerChoiceStrategies) { + expect(workerChoiceStrategy.opts).toStrictEqual({ medRunTime: true }) + } + expect( + pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime + ).toBe(false) + expect( + pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime + ).toBe(true) + pool.setWorkerChoiceStrategyOptions({ medRunTime: false }) + expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({ + medRunTime: false + }) + for (const [, workerChoiceStrategy] of pool.workerChoiceStrategyContext + .workerChoiceStrategies) { + expect(workerChoiceStrategy.opts).toStrictEqual({ medRunTime: false }) + } + expect( + pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime + ).toBe(true) + expect( + pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime + ).toBe(false) + await pool.destroy() + }) + + it('Verify that tasks queue can be enabled/disabled', async () => { + const pool = new FixedThreadPool( + numberOfWorkers, + './tests/worker-files/thread/testWorker.js' + ) + expect(pool.opts.enableTasksQueue).toBe(false) + expect(pool.opts.tasksQueueOptions).toBeUndefined() + pool.enableTasksQueue(true) + expect(pool.opts.enableTasksQueue).toBe(true) + expect(pool.opts.tasksQueueOptions).toStrictEqual({ concurrency: 1 }) + pool.enableTasksQueue(true, { concurrency: 2 }) + expect(pool.opts.enableTasksQueue).toBe(true) + expect(pool.opts.tasksQueueOptions).toStrictEqual({ concurrency: 2 }) + pool.enableTasksQueue(false) + expect(pool.opts.enableTasksQueue).toBe(false) + expect(pool.opts.tasksQueueOptions).toBeUndefined() + await pool.destroy() + }) + + it('Verify that tasks queue options can be set', async () => { + const pool = new FixedThreadPool( + numberOfWorkers, + './tests/worker-files/thread/testWorker.js', + { enableTasksQueue: true } + ) + expect(pool.opts.tasksQueueOptions).toStrictEqual({ concurrency: 1 }) + pool.setTasksQueueOptions({ concurrency: 2 }) + expect(pool.opts.tasksQueueOptions).toStrictEqual({ concurrency: 2 }) + expect(() => pool.setTasksQueueOptions({ concurrency: 0 })).toThrowError( + "Invalid worker tasks concurrency '0'" + ) + await pool.destroy() + }) + it('Simulate worker not found at getWorkerTasksUsage()', async () => { const pool = new StubPoolWithRemoveAllWorker( numberOfWorkers, diff --git a/tests/pools/selection-strategies/selection-strategies.test.js b/tests/pools/selection-strategies/selection-strategies.test.js index dde60e26..b5d59032 100644 --- a/tests/pools/selection-strategies/selection-strategies.test.js +++ b/tests/pools/selection-strategies/selection-strategies.test.js @@ -167,7 +167,8 @@ describe('Selection strategies test suite', () => { ) // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose` const promises = [] - for (let i = 0; i < max * 2; i++) { + const maxMultiplier = 2 + for (let i = 0; i < max * maxMultiplier; i++) { promises.push(pool.execute()) } await Promise.all(promises) @@ -184,7 +185,8 @@ describe('Selection strategies test suite', () => { ) // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose` const promises = [] - for (let i = 0; i < max * 2; i++) { + const maxMultiplier = 2 + for (let i = 0; i < max * maxMultiplier; i++) { promises.push(pool.execute()) } await Promise.all(promises) @@ -302,7 +304,8 @@ describe('Selection strategies test suite', () => { ) // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose` const promises = [] - for (let i = 0; i < max * 2; i++) { + const maxMultiplier = 2 + for (let i = 0; i < max * maxMultiplier; i++) { promises.push(pool.execute()) } await Promise.all(promises) @@ -319,7 +322,8 @@ describe('Selection strategies test suite', () => { ) // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose` const promises = [] - for (let i = 0; i < max * 2; i++) { + const maxMultiplier = 2 + for (let i = 0; i < max * maxMultiplier; i++) { promises.push(pool.execute()) } await Promise.all(promises) @@ -371,7 +375,8 @@ describe('Selection strategies test suite', () => { ) // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose` const promises = [] - for (let i = 0; i < max * 2; i++) { + const maxMultiplier = 2 + for (let i = 0; i < max * maxMultiplier; i++) { promises.push(pool.execute()) } await Promise.all(promises) @@ -388,7 +393,8 @@ describe('Selection strategies test suite', () => { ) // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose` const promises = [] - for (let i = 0; i < max * 2; i++) { + const maxMultiplier = 2 + for (let i = 0; i < max * maxMultiplier; i++) { promises.push(pool.execute()) } await Promise.all(promises) @@ -440,7 +446,8 @@ describe('Selection strategies test suite', () => { ) // TODO: Create a better test to cover `FairShareChoiceStrategy#choose` const promises = [] - for (let i = 0; i < max * 2; i++) { + const maxMultiplier = 2 + for (let i = 0; i < max * maxMultiplier; i++) { promises.push(pool.execute()) } await Promise.all(promises) @@ -614,7 +621,8 @@ describe('Selection strategies test suite', () => { ) // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose` const promises = [] - for (let i = 0; i < max * 2; i++) { + const maxMultiplier = 2 + for (let i = 0; i < max * maxMultiplier; i++) { promises.push(pool.execute()) } await Promise.all(promises) -- 2.34.1