feat: optimize worker choice strategies implementation
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Sun, 3 Sep 2023 09:07:57 +0000 (11:07 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Sun, 3 Sep 2023 09:07:57 +0000 (11:07 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
14 files changed:
CHANGELOG.md
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/weighted-round-robin-worker-choice-strategy.ts
src/pools/worker-node.ts
src/pools/worker.ts
tests/pools/selection-strategies/selection-strategies.test.js
tests/pools/selection-strategies/weighted-round-robin-worker-choice-strategy.test.js
typedoc.json

index 4ad7fe489eeee19c6c2f4734639f1d90f8a4755e..fed363d88a19a2a88ef7d32f8190dc57b3313ff2 100644 (file)
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## [Unreleased]
 
+### Changed
+
+- Optimize worker choice strategies implementation.
+
 ## [2.6.40] - 2023-09-01
 
 ### Fixed
index a9632d87c86d91e64407219a42402f554cac8bed..534cb49080a7127f10a366cf9b99d6187f18fb61 100644 (file)
@@ -1372,6 +1372,7 @@ export abstract class AbstractPool<
       }
       const workerNodeKey = promiseResponse.workerNodeKey
       this.afterTaskExecutionHook(workerNodeKey, message)
+      this.workerChoiceStrategyContext.update(workerNodeKey)
       this.promiseResponseMap.delete(taskId as string)
       if (
         this.opts.enableTasksQueue === true &&
@@ -1384,7 +1385,6 @@ export abstract class AbstractPool<
           this.dequeueTask(workerNodeKey) as Task<Data>
         )
       }
-      this.workerChoiceStrategyContext.update(workerNodeKey)
     }
   }
 
index 3c41dd6ffee305c8eb2f51f593df022d8889745b..999d9c866cd46aebc168cadf9408dc86ec8c0c0d 100644 (file)
@@ -153,45 +153,45 @@ export abstract class AbstractWorkerChoiceStrategy<
   }
 
   /**
-   * Gets the worker task runtime.
+   * Gets the worker node task runtime.
    * If the task statistics require the average runtime, the average runtime is returned.
    * If the task statistics require the median runtime , the median runtime is returned.
    *
    * @param workerNodeKey - The worker node key.
-   * @returns The worker task runtime.
+   * @returns The worker node task runtime.
    */
-  protected getWorkerTaskRunTime (workerNodeKey: number): number {
+  protected getWorkerNodeTaskRunTime (workerNodeKey: number): number {
     return this.taskStatisticsRequirements.runTime.median
-      ? this.pool.workerNodes[workerNodeKey].usage.runTime?.median ?? 0
-      : this.pool.workerNodes[workerNodeKey].usage.runTime?.average ?? 0
+      ? this.pool.workerNodes[workerNodeKey]?.usage?.runTime?.median ?? 0
+      : this.pool.workerNodes[workerNodeKey]?.usage?.runTime?.average ?? 0
   }
 
   /**
-   * Gets the worker task wait time.
+   * Gets the worker node task wait time.
    * If the task statistics require the average wait time, the average wait time is returned.
    * If the task statistics require the median wait time, the median wait time is returned.
    *
    * @param workerNodeKey - The worker node key.
-   * @returns The worker task wait time.
+   * @returns The worker node task wait time.
    */
-  protected getWorkerTaskWaitTime (workerNodeKey: number): number {
+  protected getWorkerNodeTaskWaitTime (workerNodeKey: number): number {
     return this.taskStatisticsRequirements.waitTime.median
-      ? this.pool.workerNodes[workerNodeKey].usage.waitTime?.median ?? 0
-      : this.pool.workerNodes[workerNodeKey].usage.waitTime?.average ?? 0
+      ? this.pool.workerNodes[workerNodeKey]?.usage?.waitTime?.median ?? 0
+      : this.pool.workerNodes[workerNodeKey]?.usage?.waitTime?.average ?? 0
   }
 
   /**
-   * Gets the worker task ELU.
+   * Gets the worker node task ELU.
    * If the task statistics require the average ELU, the average ELU is returned.
    * If the task statistics require the median ELU, the median ELU is returned.
    *
    * @param workerNodeKey - The worker node key.
-   * @returns The worker task ELU.
+   * @returns The worker node task ELU.
    */
-  protected getWorkerTaskElu (workerNodeKey: number): number {
+  protected getWorkerNodeTaskElu (workerNodeKey: number): number {
     return this.taskStatisticsRequirements.elu.median
-      ? this.pool.workerNodes[workerNodeKey].usage.elu.active?.median ?? 0
-      : this.pool.workerNodes[workerNodeKey].usage.elu.active?.average ?? 0
+      ? this.pool.workerNodes[workerNodeKey]?.usage?.elu?.active?.median ?? 0
+      : this.pool.workerNodes[workerNodeKey]?.usage?.elu?.active?.average ?? 0
   }
 
   /**
index c4a0d30beb7fe827d614ca9f434c7470aeb9d018..af3fcfa00ce06fdb369f7372e8154016a504efce 100644 (file)
@@ -3,7 +3,7 @@ import {
   DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS
 } from '../../utils'
 import type { IPool } from '../pool'
-import type { IWorker } from '../worker'
+import type { IWorker, StrategyData } from '../worker'
 import { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy'
 import {
   type IWorkerChoiceStrategy,
@@ -42,11 +42,6 @@ export class FairShareWorkerChoiceStrategy<
     }
   }
 
-  /**
-   * Workers' virtual task end execution timestamp.
-   */
-  private workersVirtualTaskEndTimestamp: number[] = []
-
   /** @inheritDoc */
   public constructor (
     pool: IPool<Worker, Data, Response>,
@@ -58,13 +53,18 @@ export class FairShareWorkerChoiceStrategy<
 
   /** @inheritDoc */
   public reset (): boolean {
-    this.workersVirtualTaskEndTimestamp = []
+    for (const workerNode of this.pool.workerNodes) {
+      delete workerNode.strategyData?.virtualTaskEndTimestamp
+    }
     return true
   }
 
   /** @inheritDoc */
   public update (workerNodeKey: number): boolean {
-    this.computeWorkerVirtualTaskEndTimestamp(workerNodeKey)
+    this.pool.workerNodes[workerNodeKey].strategyData = {
+      virtualTaskEndTimestamp:
+        this.computeWorkerNodeVirtualTaskEndTimestamp(workerNodeKey)
+    }
     return true
   }
 
@@ -76,56 +76,64 @@ export class FairShareWorkerChoiceStrategy<
   }
 
   /** @inheritDoc */
-  public remove (workerNodeKey: number): boolean {
-    this.workersVirtualTaskEndTimestamp.splice(workerNodeKey, 1)
+  public remove (): boolean {
     return true
   }
 
   private fairShareNextWorkerNodeKey (): number | undefined {
-    let chosenWorkerNodeKey: number | undefined
-    let minWorkerVirtualTaskEndTimestamp = Infinity
-    for (const [workerNodeKey] of this.pool.workerNodes.entries()) {
-      if (this.workersVirtualTaskEndTimestamp[workerNodeKey] == null) {
-        this.computeWorkerVirtualTaskEndTimestamp(workerNodeKey)
-      }
-      const workerVirtualTaskEndTimestamp =
-        this.workersVirtualTaskEndTimestamp[workerNodeKey]
-      if (workerVirtualTaskEndTimestamp < minWorkerVirtualTaskEndTimestamp) {
-        minWorkerVirtualTaskEndTimestamp = workerVirtualTaskEndTimestamp
-        chosenWorkerNodeKey = workerNodeKey
-      }
-    }
-    return chosenWorkerNodeKey
+    return this.pool.workerNodes.reduce(
+      (minWorkerNodeKey, workerNode, workerNodeKey, workerNodes) => {
+        if (workerNode.strategyData?.virtualTaskEndTimestamp == null) {
+          workerNode.strategyData = {
+            virtualTaskEndTimestamp:
+              this.computeWorkerNodeVirtualTaskEndTimestamp(workerNodeKey)
+          }
+        }
+        return (workerNode.strategyData.virtualTaskEndTimestamp as number) <
+          ((workerNodes[minWorkerNodeKey].strategyData as StrategyData)
+            .virtualTaskEndTimestamp as number)
+          ? workerNodeKey
+          : minWorkerNodeKey
+      },
+      0
+    )
   }
 
   /**
    * Computes the worker node key virtual task end timestamp.
    *
    * @param workerNodeKey - The worker node key.
+   * @returns The worker node key virtual task end timestamp.
    */
-  private computeWorkerVirtualTaskEndTimestamp (workerNodeKey: number): void {
-    this.workersVirtualTaskEndTimestamp[workerNodeKey] =
-      this.getWorkerVirtualTaskEndTimestamp(
-        workerNodeKey,
-        this.getWorkerVirtualTaskStartTimestamp(workerNodeKey)
-      )
+  private computeWorkerNodeVirtualTaskEndTimestamp (
+    workerNodeKey: number
+  ): number {
+    return this.getWorkerNodeVirtualTaskEndTimestamp(
+      workerNodeKey,
+      this.getWorkerNodeVirtualTaskStartTimestamp(workerNodeKey)
+    )
   }
 
-  private getWorkerVirtualTaskEndTimestamp (
+  private getWorkerNodeVirtualTaskEndTimestamp (
     workerNodeKey: number,
-    workerVirtualTaskStartTimestamp: number
+    workerNodeVirtualTaskStartTimestamp: number
   ): number {
-    const workerTaskRunTime =
+    const workerNodeTaskRunTime =
       this.opts.measurement === Measurements.elu
-        ? this.getWorkerTaskElu(workerNodeKey)
-        : this.getWorkerTaskRunTime(workerNodeKey)
-    return workerVirtualTaskStartTimestamp + workerTaskRunTime
+        ? this.getWorkerNodeTaskElu(workerNodeKey)
+        : this.getWorkerNodeTaskRunTime(workerNodeKey)
+    return workerNodeVirtualTaskStartTimestamp + workerNodeTaskRunTime
   }
 
-  private getWorkerVirtualTaskStartTimestamp (workerNodeKey: number): number {
-    return Math.max(
-      performance.now(),
-      this.workersVirtualTaskEndTimestamp[workerNodeKey] ?? -Infinity
-    )
+  private getWorkerNodeVirtualTaskStartTimestamp (
+    workerNodeKey: number
+  ): number {
+    const now = performance.now()
+    return now <
+      (this.pool.workerNodes[workerNodeKey]?.strategyData
+        ?.virtualTaskEndTimestamp ?? -Infinity)
+      ? (this.pool.workerNodes[workerNodeKey]?.strategyData
+          ?.virtualTaskEndTimestamp as number)
+      : now
   }
 }
index 7fba0f1b5dad0972af4ae9630b3c8565301a7863..b034cba1d08d69761b3c8f05fdedf395c4702c0a 100644 (file)
@@ -53,9 +53,9 @@ export class InterleavedWeightedRoundRobinWorkerChoiceStrategy<
    */
   private workerNodeId: number = 0
   /**
-   * Worker virtual task runtime.
+   * Worker node virtual task runtime.
    */
-  private workerVirtualTaskRunTime: number = 0
+  private workerNodeVirtualTaskRunTime: number = 0
 
   /** @inheritDoc */
   public constructor (
@@ -73,7 +73,7 @@ export class InterleavedWeightedRoundRobinWorkerChoiceStrategy<
     this.resetWorkerNodeKeyProperties()
     this.roundId = 0
     this.workerNodeId = 0
-    this.workerVirtualTaskRunTime = 0
+    this.workerNodeVirtualTaskRunTime = 0
     return true
   }
 
@@ -98,19 +98,19 @@ export class InterleavedWeightedRoundRobinWorkerChoiceStrategy<
         this.workerNodeId = workerNodeKey
         if (
           this.workerNodeId !== this.nextWorkerNodeKey &&
-          this.workerVirtualTaskRunTime !== 0
+          this.workerNodeVirtualTaskRunTime !== 0
         ) {
-          this.workerVirtualTaskRunTime = 0
+          this.workerNodeVirtualTaskRunTime = 0
         }
         const workerWeight =
           this.opts.weights?.[workerNodeKey] ?? this.defaultWorkerWeight
         if (
           workerWeight >= this.roundWeights[roundIndex] &&
-          this.workerVirtualTaskRunTime < workerWeight
+          this.workerNodeVirtualTaskRunTime < workerWeight
         ) {
-          this.workerVirtualTaskRunTime =
-            this.workerVirtualTaskRunTime +
-            this.getWorkerTaskRunTime(workerNodeKey)
+          this.workerNodeVirtualTaskRunTime =
+            this.workerNodeVirtualTaskRunTime +
+            this.getWorkerNodeTaskRunTime(workerNodeKey)
           this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey)
           this.nextWorkerNodeKey = workerNodeKey
           return this.nextWorkerNodeKey
index 0e8fdef31f27cdad48ba105554296f50df07f386..91fbfc782579f83950482ba71019c9197e5e6348 100644 (file)
@@ -72,20 +72,16 @@ export class LeastBusyWorkerChoiceStrategy<
   }
 
   private leastBusyNextWorkerNodeKey (): number | undefined {
-    let chosenWorkerNodeKey: number | undefined
-    let minTime = Infinity
-    for (const [workerNodeKey, workerNode] of this.pool.workerNodes.entries()) {
-      const workerTime =
-        (workerNode.usage.runTime?.aggregate ?? 0) +
-        (workerNode.usage.waitTime?.aggregate ?? 0)
-      if (workerTime === 0) {
-        chosenWorkerNodeKey = workerNodeKey
-        break
-      } else if (workerTime < minTime) {
-        minTime = workerTime
-        chosenWorkerNodeKey = workerNodeKey
-      }
-    }
-    return chosenWorkerNodeKey
+    return this.pool.workerNodes.reduce(
+      (minWorkerNodeKey, workerNode, workerNodeKey, workerNodes) => {
+        return (workerNode.usage.runTime?.aggregate ?? 0) +
+          (workerNode.usage.waitTime?.aggregate ?? 0) <
+          (workerNodes[minWorkerNodeKey].usage.runTime?.aggregate ?? 0) +
+            (workerNodes[minWorkerNodeKey].usage.waitTime?.aggregate ?? 0)
+          ? workerNodeKey
+          : minWorkerNodeKey
+      },
+      0
+    )
   }
 }
index 2624e5b2fdc68444d1e085452fe117655b45f282..67a1fdf387a5433999e0b1edcdd70988c6f20d5f 100644 (file)
@@ -68,19 +68,14 @@ export class LeastEluWorkerChoiceStrategy<
   }
 
   private leastEluNextWorkerNodeKey (): number | undefined {
-    let chosenWorkerNodeKey: number | undefined
-    let minWorkerElu = Infinity
-    for (const [workerNodeKey, workerNode] of this.pool.workerNodes.entries()) {
-      const workerUsage = workerNode.usage
-      const workerElu = workerUsage.elu?.active?.aggregate ?? 0
-      if (workerElu === 0) {
-        chosenWorkerNodeKey = workerNodeKey
-        break
-      } else if (workerElu < minWorkerElu) {
-        minWorkerElu = workerElu
-        chosenWorkerNodeKey = workerNodeKey
-      }
-    }
-    return chosenWorkerNodeKey
+    return this.pool.workerNodes.reduce(
+      (minWorkerNodeKey, workerNode, workerNodeKey, workerNodes) => {
+        return (workerNode.usage.elu?.active?.aggregate ?? 0) <
+          (workerNodes[minWorkerNodeKey].usage.elu?.active?.aggregate ?? 0)
+          ? workerNodeKey
+          : minWorkerNodeKey
+      },
+      0
+    )
   }
 }
index d20c32174cc553c01b120fdd055217218fc4c314..dc249e6523b9b792d52063185b1dffc3e8e37f6b 100644 (file)
@@ -53,22 +53,18 @@ export class LeastUsedWorkerChoiceStrategy<
   }
 
   private leastUsedNextWorkerNodeKey (): number | undefined {
-    let chosenWorkerNodeKey: number | undefined
-    let minNumberOfTasks = Infinity
-    for (const [workerNodeKey, workerNode] of this.pool.workerNodes.entries()) {
-      const workerTaskStatistics = workerNode.usage.tasks
-      const workerTasks =
-        workerTaskStatistics.executed +
-        workerTaskStatistics.executing +
-        workerTaskStatistics.queued
-      if (workerTasks === 0) {
-        chosenWorkerNodeKey = workerNodeKey
-        break
-      } else if (workerTasks < minNumberOfTasks) {
-        minNumberOfTasks = workerTasks
-        chosenWorkerNodeKey = workerNodeKey
-      }
-    }
-    return chosenWorkerNodeKey
+    return this.pool.workerNodes.reduce(
+      (minWorkerNodeKey, workerNode, workerNodeKey, workerNodes) => {
+        return workerNode.usage.tasks.executed +
+          workerNode.usage.tasks.executing +
+          workerNode.usage.tasks.queued <
+          workerNodes[minWorkerNodeKey].usage.tasks.executed +
+            workerNodes[minWorkerNodeKey].usage.tasks.executing +
+            workerNodes[minWorkerNodeKey].usage.tasks.queued
+          ? workerNodeKey
+          : minWorkerNodeKey
+      },
+      0
+    )
   }
 }
index b023bfb0cd258641354c81c465c20fa9a3b0b309..b9b74b6cb96634f665628d1032fd0b37a83ddef9 100644 (file)
@@ -42,9 +42,9 @@ export class WeightedRoundRobinWorkerChoiceStrategy<
    */
   private readonly defaultWorkerWeight: number
   /**
-   * Worker virtual task runtime.
+   * Worker node virtual task runtime.
    */
-  private workerVirtualTaskRunTime: number = 0
+  private workerNodeVirtualTaskRunTime: number = 0
 
   /** @inheritDoc */
   public constructor (
@@ -59,7 +59,7 @@ export class WeightedRoundRobinWorkerChoiceStrategy<
   /** @inheritDoc */
   public reset (): boolean {
     this.resetWorkerNodeKeyProperties()
-    this.workerVirtualTaskRunTime = 0
+    this.workerNodeVirtualTaskRunTime = 0
     return true
   }
 
@@ -80,7 +80,7 @@ export class WeightedRoundRobinWorkerChoiceStrategy<
       this.reset()
     }
     if (this.nextWorkerNodeKey === workerNodeKey) {
-      this.workerVirtualTaskRunTime = 0
+      this.workerNodeVirtualTaskRunTime = 0
       if (this.nextWorkerNodeKey > this.pool.workerNodes.length - 1) {
         this.nextWorkerNodeKey = this.pool.workerNodes.length - 1
       }
@@ -99,10 +99,10 @@ export class WeightedRoundRobinWorkerChoiceStrategy<
       this.opts.weights?.[
         this.nextWorkerNodeKey ?? this.previousWorkerNodeKey
       ] ?? this.defaultWorkerWeight
-    if (this.workerVirtualTaskRunTime < workerWeight) {
-      this.workerVirtualTaskRunTime =
-        this.workerVirtualTaskRunTime +
-        this.getWorkerTaskRunTime(
+    if (this.workerNodeVirtualTaskRunTime < workerWeight) {
+      this.workerNodeVirtualTaskRunTime =
+        this.workerNodeVirtualTaskRunTime +
+        this.getWorkerNodeTaskRunTime(
           this.nextWorkerNodeKey ?? this.previousWorkerNodeKey
         )
     } else {
@@ -110,7 +110,7 @@ export class WeightedRoundRobinWorkerChoiceStrategy<
         this.nextWorkerNodeKey === this.pool.workerNodes.length - 1
           ? 0
           : (this.nextWorkerNodeKey ?? this.previousWorkerNodeKey) + 1
-      this.workerVirtualTaskRunTime = 0
+      this.workerNodeVirtualTaskRunTime = 0
     }
     return this.nextWorkerNodeKey
   }
index 387d05f964270545b5b92f0e841768dea20a23df..ca275dedab806b9a4cc2c9c6aee5d3cf550b99f5 100644 (file)
@@ -13,6 +13,7 @@ import { Deque } from '../deque'
 import {
   type IWorker,
   type IWorkerNode,
+  type StrategyData,
   type WorkerInfo,
   type WorkerNodeEventCallback,
   type WorkerType,
@@ -35,6 +36,8 @@ implements IWorkerNode<Worker, Data> {
   /** @inheritdoc */
   public usage: WorkerUsage
   /** @inheritdoc */
+  public strategyData?: StrategyData
+  /** @inheritdoc */
   public messageChannel?: MessageChannel
   /** @inheritdoc */
   public tasksQueueBackPressureSize: number
index 5cd58b28be9b2ee3ef44be54af4e2fb6bdcddca2..456bf785c74eff79cf45441be1c096633ce1bc11 100644 (file)
@@ -171,6 +171,13 @@ export interface WorkerUsage {
   readonly elu: EventLoopUtilizationMeasurementStatistics
 }
 
+/**
+ * Worker strategy data.
+ */
+export interface StrategyData {
+  virtualTaskEndTimestamp?: number
+}
+
 /**
  * Worker interface.
  */
@@ -227,6 +234,11 @@ export interface IWorkerNode<Worker extends IWorker, Data = unknown> {
    * Worker usage statistics.
    */
   readonly usage: WorkerUsage
+  /**
+   * Worker strategy data.
+   * This is used to store data that is specific to the worker choice strategy.
+   */
+  strategyData?: StrategyData
   /**
    * Message channel (worker_threads only).
    */
index 51478a0620767d03730d8c441baf9e5ab4c18ea4..ab71e516ac3b4d3c8b0927c1df786e28c29eee2b 100644 (file)
@@ -123,13 +123,7 @@ describe('Selection strategies test suite', () => {
           workerChoiceStrategy
         ).previousWorkerNodeKey
       ).toBe(0)
-      if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
-        expect(
-          pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-            workerChoiceStrategy
-          ).workersVirtualTaskEndTimestamp
-        ).toStrictEqual([])
-      } else if (
+      if (
         workerChoiceStrategy === WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
       ) {
         expect(
@@ -140,7 +134,7 @@ describe('Selection strategies test suite', () => {
         expect(
           pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
             workerChoiceStrategy
-          ).workerVirtualTaskRunTime
+          ).workerNodeVirtualTaskRunTime
         ).toBe(0)
       } else if (
         workerChoiceStrategy ===
@@ -154,7 +148,7 @@ describe('Selection strategies test suite', () => {
         expect(
           pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
             workerChoiceStrategy
-          ).workerVirtualTaskRunTime
+          ).workerNodeVirtualTaskRunTime
         ).toBe(0)
         expect(
           pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1265,11 +1259,6 @@ describe('Selection strategies test suite', () => {
         pool.workerChoiceStrategyContext.workerChoiceStrategy
       ).previousWorkerNodeKey
     ).toEqual(expect.any(Number))
-    expect(
-      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-        pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).workersVirtualTaskEndTimestamp.length
-    ).toBe(pool.workerNodes.length)
     // We need to clean up the resources after our test
     await pool.destroy()
   })
@@ -1354,11 +1343,6 @@ describe('Selection strategies test suite', () => {
         pool.workerChoiceStrategyContext.workerChoiceStrategy
       ).previousWorkerNodeKey
     ).toEqual(expect.any(Number))
-    expect(
-      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-        pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).workersVirtualTaskEndTimestamp.length
-    ).toBe(pool.workerNodes.length)
     // We need to clean up the resources after our test
     await pool.destroy()
   })
@@ -1448,11 +1432,6 @@ describe('Selection strategies test suite', () => {
         pool.workerChoiceStrategyContext.workerChoiceStrategy
       ).previousWorkerNodeKey
     ).toEqual(expect.any(Number))
-    expect(
-      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-        pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).workersVirtualTaskEndTimestamp.length
-    ).toBe(pool.workerNodes.length)
     // We need to clean up the resources after our test
     await pool.destroy()
   })
@@ -1463,70 +1442,30 @@ describe('Selection strategies test suite', () => {
       max,
       './tests/worker-files/thread/testWorker.js'
     )
-    expect(
-      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-        workerChoiceStrategy
-      ).workersVirtualTaskEndTimestamp
-    ).toBeInstanceOf(Array)
-    expect(
-      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-        workerChoiceStrategy
-      ).workersVirtualTaskEndTimestamp.length
-    ).toBe(0)
-    pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-      workerChoiceStrategy
-    ).workersVirtualTaskEndTimestamp[0] = performance.now()
-    expect(
-      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-        workerChoiceStrategy
-      ).workersVirtualTaskEndTimestamp.length
-    ).toBe(1)
+    for (const workerNode of pool.workerNodes) {
+      workerNode.strategyData = {
+        virtualTaskEndTimestamp: performance.now()
+      }
+    }
     pool.setWorkerChoiceStrategy(workerChoiceStrategy)
-    expect(
-      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-        pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).workersVirtualTaskEndTimestamp
-    ).toBeInstanceOf(Array)
-    expect(
-      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-        pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).workersVirtualTaskEndTimestamp.length
-    ).toBe(0)
+    for (const workerNode of pool.workerNodes) {
+      expect(workerNode.strategyData.virtualTaskEndTimestamp).toBeUndefined()
+    }
     await pool.destroy()
     pool = new DynamicThreadPool(
       min,
       max,
       './tests/worker-files/thread/testWorker.js'
     )
-    expect(
-      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-        workerChoiceStrategy
-      ).workersVirtualTaskEndTimestamp
-    ).toBeInstanceOf(Array)
-    expect(
-      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-        workerChoiceStrategy
-      ).workersVirtualTaskEndTimestamp.length
-    ).toBe(0)
-    pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-      workerChoiceStrategy
-    ).workersVirtualTaskEndTimestamp[0] = performance.now()
-    expect(
-      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-        workerChoiceStrategy
-      ).workersVirtualTaskEndTimestamp.length
-    ).toBe(1)
+    for (const workerNode of pool.workerNodes) {
+      workerNode.strategyData = {
+        virtualTaskEndTimestamp: performance.now()
+      }
+    }
     pool.setWorkerChoiceStrategy(workerChoiceStrategy)
-    expect(
-      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-        pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).workersVirtualTaskEndTimestamp
-    ).toBeInstanceOf(Array)
-    expect(
-      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
-        pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).workersVirtualTaskEndTimestamp.length
-    ).toBe(0)
+    for (const workerNode of pool.workerNodes) {
+      expect(workerNode.strategyData.virtualTaskEndTimestamp).toBeUndefined()
+    }
     // We need to clean up the resources after our test
     await pool.destroy()
   })
@@ -1684,7 +1623,7 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).workerVirtualTaskRunTime
+      ).workerNodeVirtualTaskRunTime
     ).toBeGreaterThanOrEqual(0)
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -1762,7 +1701,7 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).workerVirtualTaskRunTime
+      ).workerNodeVirtualTaskRunTime
     ).toBeGreaterThanOrEqual(0)
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -1845,7 +1784,7 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).workerVirtualTaskRunTime
+      ).workerNodeVirtualTaskRunTime
     ).toBeGreaterThanOrEqual(0)
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -1875,7 +1814,7 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         workerChoiceStrategy
-      ).workerVirtualTaskRunTime
+      ).workerNodeVirtualTaskRunTime
     ).toBeDefined()
     pool.setWorkerChoiceStrategy(workerChoiceStrategy)
     expect(
@@ -1896,7 +1835,7 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).workerVirtualTaskRunTime
+      ).workerNodeVirtualTaskRunTime
     ).toBe(0)
     await pool.destroy()
     pool = new DynamicThreadPool(
@@ -1922,7 +1861,7 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         workerChoiceStrategy
-      ).workerVirtualTaskRunTime
+      ).workerNodeVirtualTaskRunTime
     ).toBeDefined()
     pool.setWorkerChoiceStrategy(workerChoiceStrategy)
     expect(
@@ -1943,7 +1882,7 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).workerVirtualTaskRunTime
+      ).workerNodeVirtualTaskRunTime
     ).toBe(0)
     // We need to clean up the resources after our test
     await pool.destroy()
index 9a27479bb58e33140429157adbd62b48c5a8d30c..d774bce8346c9e05f31d77b4deb3f86f13c40012 100644 (file)
@@ -33,6 +33,6 @@ describe('Weighted round robin strategy worker choice strategy test suite', () =
     expect(strategy.reset()).toBe(true)
     expect(strategy.nextWorkerNodeKey).toBe(0)
     expect(strategy.previousWorkerNodeKey).toBe(0)
-    expect(strategy.workerVirtualTaskRunTime).toBe(0)
+    expect(strategy.workerNodeVirtualTaskRunTime).toBe(0)
   })
 })
index 22e9b77b3c195754e1950ac4a4d94cbe080bb615..75f653d8f58702d43356eacfda9a16196fb131f3 100644 (file)
@@ -1,6 +1,6 @@
 {
   "$schema": "https://typedoc.org/schema.json",
-  "tsconfig": "tsconfig.production.json",
+  "tsconfig": "./tsconfig.production.json",
   "entryPoints": ["./src"],
   "out": "./docs",
   "readme": "none",