refactor: remove unneeded worker choice strategy storage in intermediate
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Sun, 31 Dec 2023 13:35:46 +0000 (14:35 +0100)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Sun, 31 Dec 2023 13:35:46 +0000 (14:35 +0100)
object

Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
17 files changed:
src/index.ts
src/pools/abstract-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/interleaved-weighted-round-robin-worker-choice-strategy.ts
src/pools/selection-strategies/least-busy-worker-choice-strategy.ts
src/pools/selection-strategies/least-elu-worker-choice-strategy.ts
src/pools/selection-strategies/least-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
src/utils.ts
tests/pools/abstract-pool.test.mjs
tests/pools/selection-strategies/selection-strategies.test.mjs
tests/pools/selection-strategies/worker-choice-strategy-context.test.mjs
tests/utils.test.mjs

index 0a9ab8f1ce44c43de8dd4e1c9e1a4617959afdd3..a18223e8c007ab88497f6b8efdc5017a45423348 100644 (file)
@@ -35,7 +35,6 @@ export {
 } from './pools/selection-strategies/selection-strategies-types.js'
 export type {
   IWorkerChoiceStrategy,
-  InternalWorkerChoiceStrategyOptions,
   Measurement,
   MeasurementOptions,
   MeasurementStatisticsRequirements,
index 31e73db14ccf1f06998329c92674f3f348a0a924..b6f3a5d08bd838426828ecd282e73f175b7e274a 100644 (file)
@@ -544,7 +544,6 @@ export abstract class AbstractPool<
       this.opts.workerChoiceStrategyOptions = workerChoiceStrategyOptions
     }
     this.workerChoiceStrategyContext.setOptions(
-      this,
       this.opts.workerChoiceStrategyOptions
     )
   }
index daed6b70093f6d3a3508bb8034b6935c0c17f729..234eada738d22ea4cd472dfe64b1d269e8983f73 100644 (file)
@@ -1,15 +1,15 @@
 import {
   DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS,
-  buildInternalWorkerChoiceStrategyOptions
+  buildWorkerChoiceStrategyOptions
 } from '../../utils.js'
 import type { IPool } from '../pool.js'
 import type { IWorker } from '../worker.js'
 import type {
   IWorkerChoiceStrategy,
-  InternalWorkerChoiceStrategyOptions,
   MeasurementStatisticsRequirements,
   StrategyPolicy,
-  TaskStatisticsRequirements
+  TaskStatisticsRequirements,
+  WorkerChoiceStrategyOptions
 } from './selection-strategies-types.js'
 
 /**
@@ -55,10 +55,10 @@ export abstract class AbstractWorkerChoiceStrategy<
    */
   public constructor (
     protected readonly pool: IPool<Worker, Data, Response>,
-    protected opts: InternalWorkerChoiceStrategyOptions
+    protected opts?: WorkerChoiceStrategyOptions
   ) {
-    this.opts = buildInternalWorkerChoiceStrategyOptions(
-      this.pool.info.maxSize,
+    this.opts = buildWorkerChoiceStrategyOptions<Worker, Data, Response>(
+      this.pool,
       this.opts
     )
     this.setTaskStatisticsRequirements(this.opts)
@@ -66,22 +66,22 @@ export abstract class AbstractWorkerChoiceStrategy<
   }
 
   protected setTaskStatisticsRequirements (
-    opts: InternalWorkerChoiceStrategyOptions
+    opts: WorkerChoiceStrategyOptions | undefined
   ): void {
     this.toggleMedianMeasurementStatisticsRequirements(
       this.taskStatisticsRequirements.runTime,
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      opts.runTime!.median
+      opts!.runTime!.median
     )
     this.toggleMedianMeasurementStatisticsRequirements(
       this.taskStatisticsRequirements.waitTime,
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      opts.waitTime!.median
+      opts!.waitTime!.median
     )
     this.toggleMedianMeasurementStatisticsRequirements(
       this.taskStatisticsRequirements.elu,
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      opts.elu!.median
+      opts!.elu!.median
     )
   }
 
@@ -117,9 +117,9 @@ export abstract class AbstractWorkerChoiceStrategy<
   public abstract remove (workerNodeKey: number): boolean
 
   /** @inheritDoc */
-  public setOptions (opts: InternalWorkerChoiceStrategyOptions): void {
-    this.opts = buildInternalWorkerChoiceStrategyOptions(
-      this.pool.info.maxSize,
+  public setOptions (opts: WorkerChoiceStrategyOptions | undefined): void {
+    this.opts = buildWorkerChoiceStrategyOptions<Worker, Data, Response>(
+      this.pool,
       opts
     )
     this.setTaskStatisticsRequirements(this.opts)
index e8f9cc619f6a7f0d8ffc596332e27a9159c72e01..58982f192ee457865e46115203b9509bdc24e29d 100644 (file)
@@ -4,9 +4,9 @@ import type { IWorker } from '../worker.js'
 import { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy.js'
 import {
   type IWorkerChoiceStrategy,
-  type InternalWorkerChoiceStrategyOptions,
   Measurements,
-  type TaskStatisticsRequirements
+  type TaskStatisticsRequirements,
+  type WorkerChoiceStrategyOptions
 } from './selection-strategies-types.js'
 
 /**
@@ -42,7 +42,7 @@ export class FairShareWorkerChoiceStrategy<
   /** @inheritDoc */
   public constructor (
     pool: IPool<Worker, Data, Response>,
-    opts: InternalWorkerChoiceStrategyOptions
+    opts?: WorkerChoiceStrategyOptions
   ) {
     super(pool, opts)
     this.setTaskStatisticsRequirements(this.opts)
@@ -118,7 +118,8 @@ export class FairShareWorkerChoiceStrategy<
     workerNodeVirtualTaskStartTimestamp: number
   ): number {
     const workerNodeTaskRunTime =
-      this.opts.measurement === Measurements.elu
+      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+      this.opts!.measurement === Measurements.elu
         ? this.getWorkerNodeTaskElu(workerNodeKey)
         : this.getWorkerNodeTaskRunTime(workerNodeKey)
     return workerNodeVirtualTaskStartTimestamp + workerNodeTaskRunTime
index fe4b48833ee98459880878c91a82204cac8408f5..3942bb6ed99961f986e1286ab20b31baf2a00eb5 100644 (file)
@@ -4,8 +4,8 @@ import { DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS } from '../../utils.js'
 import { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy.js'
 import type {
   IWorkerChoiceStrategy,
-  InternalWorkerChoiceStrategyOptions,
-  TaskStatisticsRequirements
+  TaskStatisticsRequirements,
+  WorkerChoiceStrategyOptions
 } from './selection-strategies-types.js'
 
 /**
@@ -53,7 +53,7 @@ export class InterleavedWeightedRoundRobinWorkerChoiceStrategy<
   /** @inheritDoc */
   public constructor (
     pool: IPool<Worker, Data, Response>,
-    opts: InternalWorkerChoiceStrategyOptions
+    opts?: WorkerChoiceStrategyOptions
   ) {
     super(pool, opts)
     this.setTaskStatisticsRequirements(this.opts)
@@ -95,7 +95,7 @@ export class InterleavedWeightedRoundRobinWorkerChoiceStrategy<
           this.workerNodeVirtualTaskRunTime = 0
         }
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        const workerWeight = this.opts.weights![workerNodeKey]!
+        const workerWeight = this.opts!.weights![workerNodeKey]!
         if (
           this.isWorkerNodeReady(workerNodeKey) &&
           workerWeight >= this.roundWeights[roundIndex] &&
@@ -149,7 +149,7 @@ export class InterleavedWeightedRoundRobinWorkerChoiceStrategy<
   }
 
   /** @inheritDoc */
-  public setOptions (opts: InternalWorkerChoiceStrategyOptions): void {
+  public setOptions (opts: WorkerChoiceStrategyOptions | undefined): void {
     super.setOptions(opts)
     this.roundWeights = this.getRoundWeights()
   }
@@ -158,7 +158,7 @@ export class InterleavedWeightedRoundRobinWorkerChoiceStrategy<
     return [
       ...new Set(
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        Object.values(this.opts.weights!)
+        Object.values(this.opts!.weights!)
           .slice()
           .sort((a, b) => a - b)
       )
index d800c3839af8c2675a4b7947872a72f0de385d08..0f2e123979561ce811fc7d81f9334b9d5d837e83 100644 (file)
@@ -4,8 +4,8 @@ import type { IWorker } from '../worker.js'
 import { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy.js'
 import type {
   IWorkerChoiceStrategy,
-  InternalWorkerChoiceStrategyOptions,
-  TaskStatisticsRequirements
+  TaskStatisticsRequirements,
+  WorkerChoiceStrategyOptions
 } from './selection-strategies-types.js'
 
 /**
@@ -40,7 +40,7 @@ export class LeastBusyWorkerChoiceStrategy<
   /** @inheritDoc */
   public constructor (
     pool: IPool<Worker, Data, Response>,
-    opts: InternalWorkerChoiceStrategyOptions
+    opts?: WorkerChoiceStrategyOptions
   ) {
     super(pool, opts)
     this.setTaskStatisticsRequirements(this.opts)
index 81d108a3df6e4006e531ac51d05170fc3748d7f5..588c75d9df7dd07b8ab961d9f908d6f58f4955f2 100644 (file)
@@ -4,8 +4,8 @@ import type { IWorker } from '../worker.js'
 import { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy.js'
 import type {
   IWorkerChoiceStrategy,
-  InternalWorkerChoiceStrategyOptions,
-  TaskStatisticsRequirements
+  TaskStatisticsRequirements,
+  WorkerChoiceStrategyOptions
 } from './selection-strategies-types.js'
 
 /**
@@ -36,7 +36,7 @@ export class LeastEluWorkerChoiceStrategy<
   /** @inheritDoc */
   public constructor (
     pool: IPool<Worker, Data, Response>,
-    opts: InternalWorkerChoiceStrategyOptions
+    opts?: WorkerChoiceStrategyOptions
   ) {
     super(pool, opts)
     this.setTaskStatisticsRequirements(this.opts)
index c1a4a6ac73dd8277ab6b73784a5c3bfcf6f42f89..5e8a09b42b86aae9e6b59e8ac77322b8705d890f 100644 (file)
@@ -3,7 +3,7 @@ import type { IWorker } from '../worker.js'
 import { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy.js'
 import type {
   IWorkerChoiceStrategy,
-  InternalWorkerChoiceStrategyOptions
+  WorkerChoiceStrategyOptions
 } from './selection-strategies-types.js'
 
 /**
@@ -23,7 +23,7 @@ export class LeastUsedWorkerChoiceStrategy<
   /** @inheritDoc */
   public constructor (
     pool: IPool<Worker, Data, Response>,
-    opts: InternalWorkerChoiceStrategyOptions
+    opts?: WorkerChoiceStrategyOptions
   ) {
     super(pool, opts)
   }
index 34c4f596db2af9c3f44e7940c9444effc9d44b77..41326a78ea0ec3ea2b198de4255c827774422f1b 100644 (file)
@@ -3,7 +3,7 @@ import type { IWorker } from '../worker.js'
 import { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy.js'
 import type {
   IWorkerChoiceStrategy,
-  InternalWorkerChoiceStrategyOptions
+  WorkerChoiceStrategyOptions
 } from './selection-strategies-types.js'
 
 /**
@@ -23,7 +23,7 @@ export class RoundRobinWorkerChoiceStrategy<
   /** @inheritDoc */
   public constructor (
     pool: IPool<Worker, Data, Response>,
-    opts: InternalWorkerChoiceStrategyOptions
+    opts?: WorkerChoiceStrategyOptions
   ) {
     super(pool, opts)
   }
index 1467ab4f566317742dca3f453d6cfedff860fa16..d30f9eeb5c4007250643d03cf36fd26993586618 100644 (file)
@@ -98,21 +98,6 @@ export interface WorkerChoiceStrategyOptions {
   weights?: Record<number, number>
 }
 
-/**
- * Worker choice strategy internal options.
- *
- * @internal
- */
-export interface InternalWorkerChoiceStrategyOptions
-  extends WorkerChoiceStrategyOptions {
-  /**
-   * Number of worker choice retries to perform if no worker is eligible.
-   *
-   * @defaultValue pool maximum size
-   */
-  readonly retries?: number
-}
-
 /**
  * Measurement statistics requirements.
  *
@@ -216,7 +201,7 @@ export interface IWorkerChoiceStrategy {
    *
    * @param opts - The worker choice strategy options.
    */
-  readonly setOptions: (opts: WorkerChoiceStrategyOptions) => void
+  readonly setOptions: (opts: WorkerChoiceStrategyOptions | undefined) => void
   /**
    * Whether the pool has worker nodes ready or not.
    *
index 5ccc9c320ac6e09cce290c8a848c4e0ebdb60006..6bbbbaf64738527cafb2720ae9a5ba73d7544c0e 100644 (file)
@@ -4,8 +4,8 @@ import { DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS } from '../../utils.js'
 import { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy.js'
 import type {
   IWorkerChoiceStrategy,
-  InternalWorkerChoiceStrategyOptions,
-  TaskStatisticsRequirements
+  TaskStatisticsRequirements,
+  WorkerChoiceStrategyOptions
 } from './selection-strategies-types.js'
 
 /**
@@ -42,7 +42,7 @@ export class WeightedRoundRobinWorkerChoiceStrategy<
   /** @inheritDoc */
   public constructor (
     pool: IPool<Worker, Data, Response>,
-    opts: InternalWorkerChoiceStrategyOptions
+    opts?: WorkerChoiceStrategyOptions
   ) {
     super(pool, opts)
     this.setTaskStatisticsRequirements(this.opts)
@@ -91,7 +91,7 @@ export class WeightedRoundRobinWorkerChoiceStrategy<
   private weightedRoundRobinNextWorkerNodeKey (): number | undefined {
     const workerWeight =
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      this.opts.weights![this.nextWorkerNodeKey ?? this.previousWorkerNodeKey]!
+      this.opts!.weights![this.nextWorkerNodeKey ?? this.previousWorkerNodeKey]!
     if (this.workerNodeVirtualTaskRunTime < workerWeight) {
       this.workerNodeVirtualTaskRunTime =
         this.workerNodeVirtualTaskRunTime +
index 330e584d4a1fd74e0878bb820afb538d2c7a72ec..d3e7f03e6ba520ab69c2996dd97d0dbe9302ab48 100644 (file)
@@ -1,6 +1,6 @@
-import { buildInternalWorkerChoiceStrategyOptions } from '../../utils.js'
 import type { IPool } from '../pool.js'
 import type { IWorker } from '../worker.js'
+import { getWorkerChoiceStrategyRetries } from '../../utils.js'
 import { FairShareWorkerChoiceStrategy } from './fair-share-worker-choice-strategy.js'
 import { InterleavedWeightedRoundRobinWorkerChoiceStrategy } from './interleaved-weighted-round-robin-worker-choice-strategy.js'
 import { LeastBusyWorkerChoiceStrategy } from './least-busy-worker-choice-strategy.js'
@@ -9,10 +9,10 @@ import { LeastEluWorkerChoiceStrategy } from './least-elu-worker-choice-strategy
 import { RoundRobinWorkerChoiceStrategy } from './round-robin-worker-choice-strategy.js'
 import type {
   IWorkerChoiceStrategy,
-  InternalWorkerChoiceStrategyOptions,
   StrategyPolicy,
   TaskStatisticsRequirements,
-  WorkerChoiceStrategy
+  WorkerChoiceStrategy,
+  WorkerChoiceStrategyOptions
 } from './selection-strategies-types.js'
 import { WorkerChoiceStrategies } from './selection-strategies-types.js'
 import { WeightedRoundRobinWorkerChoiceStrategy } from './weighted-round-robin-worker-choice-strategy.js'
@@ -29,11 +29,19 @@ export class WorkerChoiceStrategyContext<
   Data = unknown,
   Response = unknown
 > {
+  /**
+   * The worker choice strategies registered in the context.
+   */
   private readonly workerChoiceStrategies: Map<
   WorkerChoiceStrategy,
   IWorkerChoiceStrategy
   >
 
+  /**
+   * The number of worker choice strategy execution retries.
+   */
+  private readonly retries: number
+
   /**
    * Worker choice strategy context constructor.
    *
@@ -44,12 +52,8 @@ export class WorkerChoiceStrategyContext<
   public constructor (
     pool: IPool<Worker, Data, Response>,
     private workerChoiceStrategy: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN,
-    private opts?: InternalWorkerChoiceStrategyOptions
+    opts?: WorkerChoiceStrategyOptions
   ) {
-    this.opts = buildInternalWorkerChoiceStrategyOptions(
-      pool.info.maxSize,
-      this.opts
-    )
     this.execute = this.execute.bind(this)
     this.workerChoiceStrategies = new Map<
     WorkerChoiceStrategy,
@@ -59,35 +63,35 @@ export class WorkerChoiceStrategyContext<
         WorkerChoiceStrategies.ROUND_ROBIN,
         new (RoundRobinWorkerChoiceStrategy.bind(this))<Worker, Data, Response>(
           pool,
-          this.opts
+          opts
         )
       ],
       [
         WorkerChoiceStrategies.LEAST_USED,
         new (LeastUsedWorkerChoiceStrategy.bind(this))<Worker, Data, Response>(
           pool,
-          this.opts
+          opts
         )
       ],
       [
         WorkerChoiceStrategies.LEAST_BUSY,
         new (LeastBusyWorkerChoiceStrategy.bind(this))<Worker, Data, Response>(
           pool,
-          this.opts
+          opts
         )
       ],
       [
         WorkerChoiceStrategies.LEAST_ELU,
         new (LeastEluWorkerChoiceStrategy.bind(this))<Worker, Data, Response>(
           pool,
-          this.opts
+          opts
         )
       ],
       [
         WorkerChoiceStrategies.FAIR_SHARE,
         new (FairShareWorkerChoiceStrategy.bind(this))<Worker, Data, Response>(
           pool,
-          this.opts
+          opts
         )
       ],
       [
@@ -96,7 +100,7 @@ export class WorkerChoiceStrategyContext<
         Worker,
         Data,
         Response
-        >(pool, this.opts)
+        >(pool, opts)
       ],
       [
         WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN,
@@ -104,9 +108,10 @@ export class WorkerChoiceStrategyContext<
         Worker,
         Data,
         Response
-        >(pool, this.opts)
+        >(pool, opts)
       ]
     ])
+    this.retries = getWorkerChoiceStrategyRetries(pool, opts)
   }
 
   /**
@@ -191,8 +196,7 @@ export class WorkerChoiceStrategyContext<
         retriesCount++
       }
       chooseCount++
-      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    } while (workerNodeKey == null && retriesCount < this.opts!.retries!)
+    } while (workerNodeKey == null && retriesCount < this.retries)
     if (workerNodeKey == null) {
       throw new Error(
         `Worker node key chosen is null or undefined after ${retriesCount} retries`
@@ -217,19 +221,11 @@ export class WorkerChoiceStrategyContext<
   /**
    * Sets the worker choice strategies in the context options.
    *
-   * @param pool - The pool instance.
    * @param opts - The worker choice strategy options.
    */
-  public setOptions (
-    pool: IPool<Worker, Data, Response>,
-    opts?: InternalWorkerChoiceStrategyOptions
-  ): void {
-    this.opts = buildInternalWorkerChoiceStrategyOptions(
-      pool.info.maxSize,
-      opts
-    )
+  public setOptions (opts: WorkerChoiceStrategyOptions | undefined): void {
     for (const workerChoiceStrategy of this.workerChoiceStrategies.values()) {
-      workerChoiceStrategy.setOptions(this.opts)
+      workerChoiceStrategy.setOptions(opts)
     }
   }
 }
index c8aed4421bb8f7f9a8262683b02cefa4b6a6ff5b..a7cb55f971483d12729e259110b3d872da7b5f15 100644 (file)
@@ -4,11 +4,12 @@ import { Worker as ClusterWorker } from 'node:cluster'
 import { Worker as ThreadWorker } from 'node:worker_threads'
 import { cpus } from 'node:os'
 import type {
-  InternalWorkerChoiceStrategyOptions,
-  MeasurementStatisticsRequirements
+  MeasurementStatisticsRequirements,
+  WorkerChoiceStrategyOptions
 } from './pools/selection-strategies/selection-strategies-types.js'
 import type { KillBehavior } from './worker/worker-options.js'
 import { type IWorker, type WorkerType, WorkerTypes } from './pools/worker.js'
+import type { IPool } from './pools/pool.js'
 
 /**
  * Default task name.
@@ -22,23 +23,6 @@ export const EMPTY_FUNCTION: () => void = Object.freeze(() => {
   /* Intentionally empty */
 })
 
-/**
- * Gets default worker choice strategy options.
- *
- * @param retries - The number of worker choice retries.
- * @returns The default worker choice strategy options.
- */
-const getDefaultInternalWorkerChoiceStrategyOptions = (
-  retries: number
-): InternalWorkerChoiceStrategyOptions => {
-  return {
-    retries,
-    runTime: { median: false },
-    waitTime: { median: false },
-    elu: { median: false }
-  }
-}
-
 /**
  * Default measurement statistics requirements.
  */
@@ -282,22 +266,40 @@ export const once = <T, A extends any[], R>(
   }
 }
 
+export const getWorkerChoiceStrategyRetries = <
+  Worker extends IWorker,
+  Data,
+  Response
+>(
+    pool: IPool<Worker, Data, Response>,
+    opts?: WorkerChoiceStrategyOptions
+  ): number => {
+  return (
+    pool.info.maxSize +
+    Object.keys(opts?.weights ?? getDefaultWeights(pool.info.maxSize)).length
+  )
+}
+
 const clone = <T>(object: T): T => {
   return structuredClone<T>(object)
 }
 
-export const buildInternalWorkerChoiceStrategyOptions = (
-  poolMaxSize: number,
-  opts?: InternalWorkerChoiceStrategyOptions
-): InternalWorkerChoiceStrategyOptions => {
+export const buildWorkerChoiceStrategyOptions = <
+  Worker extends IWorker,
+  Data,
+  Response
+>(
+    pool: IPool<Worker, Data, Response>,
+    opts?: WorkerChoiceStrategyOptions
+  ): WorkerChoiceStrategyOptions => {
   opts = clone(opts ?? {})
-  if (opts?.weights == null) {
-    opts.weights = getDefaultWeights(poolMaxSize)
-  }
+  opts.weights = opts?.weights ?? getDefaultWeights(pool.info.maxSize)
   return {
-    ...getDefaultInternalWorkerChoiceStrategyOptions(
-      poolMaxSize + Object.keys(opts.weights).length
-    ),
+    ...{
+      runTime: { median: false },
+      waitTime: { median: false },
+      elu: { median: false }
+    },
     ...opts
   }
 }
index a10222610c4ee064164fba8b03d55879db0472a9..ccd2423102427a40878faf2ee347aa20f3f58964 100644 (file)
@@ -228,24 +228,9 @@ describe('Abstract pool test suite', () => {
       enableTasksQueue: false,
       workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN
     })
-    expect(pool.workerChoiceStrategyContext.opts).toStrictEqual({
-      retries:
-        pool.info.maxSize +
-        Object.keys(pool.workerChoiceStrategyContext.opts.weights).length,
-      runTime: { median: false },
-      waitTime: { median: false },
-      elu: { median: false },
-      weights: expect.objectContaining({
-        0: expect.any(Number),
-        [pool.info.maxSize - 1]: expect.any(Number)
-      })
-    })
     for (const [, workerChoiceStrategy] of pool.workerChoiceStrategyContext
       .workerChoiceStrategies) {
       expect(workerChoiceStrategy.opts).toStrictEqual({
-        retries:
-          pool.info.maxSize +
-          Object.keys(workerChoiceStrategy.opts.weights).length,
         runTime: { median: false },
         waitTime: { median: false },
         elu: { median: false },
@@ -299,21 +284,9 @@ describe('Abstract pool test suite', () => {
       errorHandler: testHandler,
       exitHandler: testHandler
     })
-    expect(pool.workerChoiceStrategyContext.opts).toStrictEqual({
-      retries:
-        pool.info.maxSize +
-        Object.keys(pool.opts.workerChoiceStrategyOptions.weights).length,
-      runTime: { median: true },
-      waitTime: { median: false },
-      elu: { median: false },
-      weights: { 0: 300, 1: 200 }
-    })
     for (const [, workerChoiceStrategy] of pool.workerChoiceStrategyContext
       .workerChoiceStrategies) {
       expect(workerChoiceStrategy.opts).toStrictEqual({
-        retries:
-          pool.info.maxSize +
-          Object.keys(pool.opts.workerChoiceStrategyOptions.weights).length,
         runTime: { median: true },
         waitTime: { median: false },
         elu: { median: false },
@@ -470,24 +443,9 @@ describe('Abstract pool test suite', () => {
       { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE }
     )
     expect(pool.opts.workerChoiceStrategyOptions).toBeUndefined()
-    expect(pool.workerChoiceStrategyContext.opts).toStrictEqual({
-      retries:
-        pool.info.maxSize +
-        Object.keys(pool.workerChoiceStrategyContext.opts.weights).length,
-      runTime: { median: false },
-      waitTime: { median: false },
-      elu: { median: false },
-      weights: expect.objectContaining({
-        0: expect.any(Number),
-        [pool.info.maxSize - 1]: expect.any(Number)
-      })
-    })
     for (const [, workerChoiceStrategy] of pool.workerChoiceStrategyContext
       .workerChoiceStrategies) {
       expect(workerChoiceStrategy.opts).toStrictEqual({
-        retries:
-          pool.info.maxSize +
-          Object.keys(workerChoiceStrategy.opts.weights).length,
         runTime: { median: false },
         waitTime: { median: false },
         elu: { median: false },
@@ -524,24 +482,9 @@ describe('Abstract pool test suite', () => {
       runTime: { median: true },
       elu: { median: true }
     })
-    expect(pool.workerChoiceStrategyContext.opts).toStrictEqual({
-      retries:
-        pool.info.maxSize +
-        Object.keys(pool.workerChoiceStrategyContext.opts.weights).length,
-      runTime: { median: true },
-      waitTime: { median: false },
-      elu: { median: true },
-      weights: expect.objectContaining({
-        0: expect.any(Number),
-        [pool.info.maxSize - 1]: expect.any(Number)
-      })
-    })
     for (const [, workerChoiceStrategy] of pool.workerChoiceStrategyContext
       .workerChoiceStrategies) {
       expect(workerChoiceStrategy.opts).toStrictEqual({
-        retries:
-          pool.info.maxSize +
-          Object.keys(workerChoiceStrategy.opts.weights).length,
         runTime: { median: true },
         waitTime: { median: false },
         elu: { median: true },
@@ -578,24 +521,9 @@ describe('Abstract pool test suite', () => {
       runTime: { median: false },
       elu: { median: false }
     })
-    expect(pool.workerChoiceStrategyContext.opts).toStrictEqual({
-      retries:
-        pool.info.maxSize +
-        Object.keys(pool.workerChoiceStrategyContext.opts.weights).length,
-      runTime: { median: false },
-      waitTime: { median: false },
-      elu: { median: false },
-      weights: expect.objectContaining({
-        0: expect.any(Number),
-        [pool.info.maxSize - 1]: expect.any(Number)
-      })
-    })
     for (const [, workerChoiceStrategy] of pool.workerChoiceStrategyContext
       .workerChoiceStrategies) {
       expect(workerChoiceStrategy.opts).toStrictEqual({
-        retries:
-          pool.info.maxSize +
-          Object.keys(workerChoiceStrategy.opts.weights).length,
         runTime: { median: false },
         waitTime: { median: false },
         elu: { median: false },
index 39a2ccc3f7ce0cd84ad995165a85a9227341c688..8dc06262d2d35418b1ff050bff843ce03b1efe97 100644 (file)
@@ -66,19 +66,6 @@ describe('Selection strategies test suite', () => {
       expect(pool.workerChoiceStrategyContext.workerChoiceStrategy).toBe(
         workerChoiceStrategy
       )
-      expect(pool.opts.workerChoiceStrategyOptions).toBeUndefined()
-      expect(pool.workerChoiceStrategyContext.opts).toStrictEqual({
-        retries:
-          pool.info.maxSize +
-          Object.keys(pool.workerChoiceStrategyContext.opts.weights).length,
-        runTime: { median: false },
-        waitTime: { median: false },
-        elu: { median: false },
-        weights: expect.objectContaining({
-          0: expect.any(Number),
-          [pool.info.maxSize - 1]: expect.any(Number)
-        })
-      })
       await pool.destroy()
     }
     for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) {
@@ -92,19 +79,6 @@ describe('Selection strategies test suite', () => {
       expect(pool.workerChoiceStrategyContext.workerChoiceStrategy).toBe(
         workerChoiceStrategy
       )
-      expect(pool.opts.workerChoiceStrategyOptions).toBeUndefined()
-      expect(pool.workerChoiceStrategyContext.opts).toStrictEqual({
-        retries:
-          pool.info.maxSize +
-          Object.keys(pool.workerChoiceStrategyContext.opts.weights).length,
-        runTime: { median: false },
-        waitTime: { median: false },
-        elu: { median: false },
-        weights: expect.objectContaining({
-          0: expect.any(Number),
-          [pool.info.maxSize - 1]: expect.any(Number)
-        })
-      })
       await pool.destroy()
     }
   })
index 6615b8c445f0b069b645577017f2725685a0bafa..85ec426359c3fdbc0e0830404fe02d56886d7d99 100644 (file)
@@ -41,14 +41,25 @@ describe('Worker choice strategy context test suite', () => {
   })
 
   it('Verify that constructor() initializes the context with all the available worker choice strategies', () => {
-    const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
-      fixedPool
+    let workerChoiceStrategyContext = new WorkerChoiceStrategyContext(fixedPool)
+    expect(workerChoiceStrategyContext.workerChoiceStrategies.size).toBe(
+      Object.keys(WorkerChoiceStrategies).length
     )
+    workerChoiceStrategyContext = new WorkerChoiceStrategyContext(dynamicPool)
     expect(workerChoiceStrategyContext.workerChoiceStrategies.size).toBe(
       Object.keys(WorkerChoiceStrategies).length
     )
   })
 
+  it('Verify that constructor() initializes the context with retries attribute properly set', () => {
+    let workerChoiceStrategyContext = new WorkerChoiceStrategyContext(fixedPool)
+    expect(workerChoiceStrategyContext.retries).toBe(fixedPool.info.maxSize * 2)
+    workerChoiceStrategyContext = new WorkerChoiceStrategyContext(dynamicPool)
+    expect(workerChoiceStrategyContext.retries).toBe(
+      dynamicPool.info.maxSize * 2
+    )
+  })
+
   it('Verify that execute() return the worker node key chosen by the strategy with fixed pool', () => {
     const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
       fixedPool
@@ -96,10 +107,7 @@ describe('Worker choice strategy context test suite', () => {
     )
     expect(() => workerChoiceStrategyContext.execute()).toThrow(
       new Error(
-        `Worker node key chosen is null or undefined after ${
-          fixedPool.info.maxSize +
-          Object.keys(workerChoiceStrategyContext.opts.weights).length
-        } retries`
+        `Worker node key chosen is null or undefined after ${workerChoiceStrategyContext.retries} retries`
       )
     )
     const workerChoiceStrategyNullStub = createStubInstance(
@@ -115,10 +123,7 @@ describe('Worker choice strategy context test suite', () => {
     )
     expect(() => workerChoiceStrategyContext.execute()).toThrow(
       new Error(
-        `Worker node key chosen is null or undefined after ${
-          fixedPool.info.maxSize +
-          Object.keys(workerChoiceStrategyContext.opts.weights).length
-        } retries`
+        `Worker node key chosen is null or undefined after ${workerChoiceStrategyContext.retries} retries`
       )
     )
   })
index 2d1ee9e6f3c70d70bf103793fea14d0dbadb80d2..5e089e291f07877506ff12a3373ca407ee2b5c51 100644 (file)
@@ -9,8 +9,9 @@ import {
   EMPTY_FUNCTION,
   availableParallelism,
   average,
-  buildInternalWorkerChoiceStrategyOptions,
+  buildWorkerChoiceStrategyOptions,
   exponentialDelay,
+  getWorkerChoiceStrategyRetries,
   getWorkerId,
   getWorkerType,
   isAsyncFunction,
@@ -24,7 +25,12 @@ import {
   secureRandom,
   sleep
 } from '../lib/utils.cjs'
-import { KillBehaviors, WorkerTypes } from '../lib/index.cjs'
+import {
+  FixedClusterPool,
+  FixedThreadPool,
+  KillBehaviors,
+  WorkerTypes
+} from '../lib/index.cjs'
 
 describe('Utils test suite', () => {
   it('Verify DEFAULT_TASK_NAME value', () => {
@@ -231,22 +237,32 @@ describe('Utils test suite', () => {
     expect(max(1, 1)).toBe(1)
   })
 
-  it('Verify buildInternalWorkerChoiceStrategyOptions() behavior', () => {
-    const poolMaxSize = 10
-    const internalWorkerChoiceStrategyOptions =
-      buildInternalWorkerChoiceStrategyOptions(poolMaxSize)
-    expect(internalWorkerChoiceStrategyOptions).toStrictEqual({
-      retries:
-        poolMaxSize +
-        Object.keys(internalWorkerChoiceStrategyOptions.weights).length,
+  it('Verify getWorkerChoiceStrategyRetries() behavior', async () => {
+    const numberOfThreads = 4
+    const pool = new FixedThreadPool(
+      numberOfThreads,
+      './tests/worker-files/thread/testWorker.mjs'
+    )
+    expect(getWorkerChoiceStrategyRetries(pool)).toBe(pool.info.maxSize * 2)
+    await pool.destroy()
+  })
+
+  it('Verify buildWorkerChoiceStrategyOptions() behavior', async () => {
+    const numberOfWorkers = 4
+    const pool = new FixedClusterPool(
+      numberOfWorkers,
+      './tests/worker-files/cluster/testWorker.cjs'
+    )
+    expect(buildWorkerChoiceStrategyOptions(pool)).toStrictEqual({
       runTime: { median: false },
       waitTime: { median: false },
       elu: { median: false },
       weights: expect.objectContaining({
         0: expect.any(Number),
-        [poolMaxSize - 1]: expect.any(Number)
+        [pool.info.maxSize - 1]: expect.any(Number)
       })
     })
+    await pool.destroy()
   })
 
   // it('Verify once()', () => {