feat: add pool runtime setters
authorJérôme Benoit <jerome.benoit@sap.com>
Sat, 15 Apr 2023 11:36:34 +0000 (13:36 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Sat, 15 Apr 2023 11:36:34 +0000 (13:36 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
15 files changed:
CHANGELOG.md
package.json
pnpm-lock.yaml
src/pools/abstract-pool.ts
src/pools/pool.ts
src/pools/selection-strategies/abstract-worker-choice-strategy.ts
src/pools/selection-strategies/fair-share-worker-choice-strategy.ts
src/pools/selection-strategies/less-busy-worker-choice-strategy.ts
src/pools/selection-strategies/less-used-worker-choice-strategy.ts
src/pools/selection-strategies/round-robin-worker-choice-strategy.ts
src/pools/selection-strategies/selection-strategies-types.ts
src/pools/selection-strategies/weighted-round-robin-worker-choice-strategy.ts
src/pools/selection-strategies/worker-choice-strategy-context.ts
tests/pools/abstract/abstract-pool.test.js
tests/pools/selection-strategies/selection-strategies.test.js

index 5d599b1622c13695557c90f33b93b8cf61735793..381fa711ad9d798f532b33a66b8b11c3524e2317 100644 (file)
@@ -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.
index a2812dcd831b52ea437c5da581a0fcdd5513cdfd..ef5ef8566574502f1d145eb13cd3e0d33e04f90b 100644 (file)
     "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",
index 229d36d05133fa69e8de563dd1ba11c7a427dc55..3f111a26e3a835cbd24cb7533157f041e1ae57b3 100644 (file)
@@ -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
index 3be40e6d9cc8dd2634ab02569abd6261dca6f326..f1c6ad13af6ea51de124cfb8545c65e2af5e01e8 100644 (file)
@@ -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.
    *
index 83e01eb723557b26dbba8663908424e7d3295299..ea60833a42b445921ef162d15d651a9ba32d6127 100644 (file)
@@ -98,14 +98,11 @@ export interface PoolOptions<Worker extends IWorker> {
   /**
    * 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
 }
index 77b44f6e344547154a0091ca8f17a82bdf1a7cb2..859ead823bc233c6e251eb004e7d6fb0563459e6 100644 (file)
@@ -36,7 +36,7 @@ export abstract class AbstractWorkerChoiceStrategy<
    */
   public constructor (
     protected readonly pool: IPool<Worker, Data, Response>,
-    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
+  }
 }
index 81944f7a6c1d0342889b716a26be5b23cc34034e..4d6ef2a828fc2b21cd2356886118649e5baacd4f 100644 (file)
@@ -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 */
index 708c491f63dea4183232c20f5d1c7373d14738ba..d862405c2e07b224602e21093f235675ee8c750c 100644 (file)
@@ -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 */
index 1138df952a4600b31ff4f60a5540b94f035b31b3..51039c95173f8dda07116c0876b5f26ef93dbd5b 100644 (file)
@@ -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 */
index 107e9639b38466e3d832fd217885b21b27206f12..d2d6f6d6574a23b092da2323957b312deee13d4d 100644 (file)
@@ -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 */
index 065b310fa5e8a3454f84d5b0edd6324c7c2d0520..f9a504351a4bbbe9d33bddc145c457a7ce27ef78 100644 (file)
@@ -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
 }
index dc2e5df3f170a1c8d65118e705d6b0754cebf56b..c5c204373e67e7135b590eb8b3faa709f156f26d 100644 (file)
@@ -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()
   }
index b075c4eac5ae3cd9cd88b41553263b11e2e5af95..5e9f7de9dce24e1510e52d68c09bfb6486df1f52 100644 (file)
@@ -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)
+    })
+  }
 }
index 86506f671f29848f2a8f56f25943f708f886de03..54f9382ab9c7d8f0064d699fa0c7a56bba8a4295 100644 (file)
@@ -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,
index dde60e2685cdfd521708d3869fb935bb4e5cf691..b5d5903226b9979d0b455548a603eb4df3608512 100644 (file)
@@ -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)