refactor: untangle worker choosing code from worker creation code
authorJérôme Benoit <jerome.benoit@sap.com>
Fri, 7 Apr 2023 16:46:42 +0000 (18:46 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Fri, 7 Apr 2023 16:46:42 +0000 (18:46 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
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/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

index 97225246cde2e8baab84cd2a60968ca7d09aa079..2e033fc1614c0a778c85569d98cb8e014f010bcc 100644 (file)
@@ -93,23 +93,7 @@ export abstract class AbstractPool<
     Worker,
     Data,
     Response
-    >(
-      this,
-      () => {
-        const createdWorker = this.createAndSetupWorker()
-        this.registerWorkerMessageListener(createdWorker, message => {
-          if (
-            isKillBehavior(KillBehaviors.HARD, message.kill) ||
-            this.getWorkerTasksUsage(createdWorker)?.running === 0
-          ) {
-            // Kill received from the worker, means that no new tasks are submitted to that worker for a while ( > maxInactiveTime)
-            void this.destroyWorker(createdWorker)
-          }
-        })
-        return this.getWorkerKey(createdWorker)
-      },
-      this.opts.workerChoiceStrategy
-    )
+    >(this, this.opts.workerChoiceStrategy)
   }
 
   private checkFilePath (filePath: string): void {
@@ -308,7 +292,26 @@ export abstract class AbstractPool<
    * @returns [worker key, worker].
    */
   protected chooseWorker (): [number, Worker] {
-    const workerKey = this.workerChoiceStrategyContext.execute()
+    let workerKey: number
+    if (
+      this.type === PoolType.DYNAMIC &&
+      !this.full &&
+      this.findFreeWorkerKey() === -1
+    ) {
+      const createdWorker = this.createAndSetupWorker()
+      this.registerWorkerMessageListener(createdWorker, message => {
+        if (
+          isKillBehavior(KillBehaviors.HARD, message.kill) ||
+          this.getWorkerTasksUsage(createdWorker)?.running === 0
+        ) {
+          // Kill received from the worker, means that no new tasks are submitted to that worker for a while ( > maxInactiveTime)
+          void this.destroyWorker(createdWorker)
+        }
+      })
+      workerKey = this.getWorkerKey(createdWorker)
+    } else {
+      workerKey = this.workerChoiceStrategyContext.execute()
+    }
     return [workerKey, this.workers[workerKey].worker]
   }
 
index 0d337b53191f4a991368ea66976761d95fda1027..f32229ec3da8550d49263f2ed76a434a63d6d97b 100644 (file)
@@ -17,7 +17,7 @@ export abstract class AbstractWorkerChoiceStrategy<
   Worker extends IPoolWorker,
   Data = unknown,
   Response = unknown
-> implements IWorkerChoiceStrategy<Worker, Data, Response> {
+> implements IWorkerChoiceStrategy {
   /** @inheritDoc */
   public readonly isDynamicPool: boolean
   /** @inheritDoc */
index f8427d01bab393ae47c9d6975d31e14338f5c74d..16d5a7be1dd60ca213a873c1571f8335948ac826 100644 (file)
@@ -27,7 +27,7 @@ export class FairShareWorkerChoiceStrategy<
     Response = unknown
   >
   extends AbstractWorkerChoiceStrategy<Worker, Data, Response>
-  implements IWorkerChoiceStrategy<Worker, Data, Response> {
+  implements IWorkerChoiceStrategy {
   /** @inheritDoc */
   public readonly requiredStatistics: RequiredStatistics = {
     runTime: true,
index a9c5500462df9ddafa004bc9988b27fe6177007b..87ef804d50881f157e2810a715c2db4627315f33 100644 (file)
@@ -18,7 +18,7 @@ export class LessBusyWorkerChoiceStrategy<
     Response = unknown
   >
   extends AbstractWorkerChoiceStrategy<Worker, Data, Response>
-  implements IWorkerChoiceStrategy<Worker, Data, Response> {
+  implements IWorkerChoiceStrategy {
   /** @inheritDoc */
   public readonly requiredStatistics: RequiredStatistics = {
     runTime: true,
index f3b45e06ccd671ef782cdcb87e8264858ac48732..364c54a1d3b5d6d0a5a1c853221a247c15cdd1fa 100644 (file)
@@ -15,7 +15,7 @@ export class LessUsedWorkerChoiceStrategy<
     Response = unknown
   >
   extends AbstractWorkerChoiceStrategy<Worker, Data, Response>
-  implements IWorkerChoiceStrategy<Worker, Data, Response> {
+  implements IWorkerChoiceStrategy {
   /** @inheritDoc */
   public reset (): boolean {
     return true
index 9cc966c47956a9a1689f82a435168127bbfbd272..29b05fa507f0b3ca8a18a300ad1c6927d9b76a65 100644 (file)
@@ -15,7 +15,7 @@ export class RoundRobinWorkerChoiceStrategy<
     Response = unknown
   >
   extends AbstractWorkerChoiceStrategy<Worker, Data, Response>
-  implements IWorkerChoiceStrategy<Worker, Data, Response> {
+  implements IWorkerChoiceStrategy {
   /**
    * Id of the next worker.
    */
index 137c1be7562e50309818763f556651aed2034b04..9acf819b8b858900a1d42a5a681d7f001b152edf 100644 (file)
@@ -1,6 +1,3 @@
-import type { IPoolInternal } from '../pool-internal'
-import type { IPoolWorker } from '../pool-worker'
-
 /**
  * Enumeration of worker choice strategies.
  */
@@ -43,15 +40,7 @@ export interface RequiredStatistics {
 /**
  * Worker choice strategy interface.
  */
-export interface IWorkerChoiceStrategy<
-  Worker extends IPoolWorker,
-  Data = unknown,
-  Response = unknown
-> {
-  /**
-   * The pool instance.
-   */
-  readonly pool: IPoolInternal<Worker, Data, Response>
+export interface IWorkerChoiceStrategy {
   /**
    * Is the pool bound to the strategy dynamic?.
    */
index 997366cd5984c49fe973896b8dce8ce4d389e4f2..ea598b207f2e1b20358ce0cd6c5da134077ae8f1 100644 (file)
@@ -29,7 +29,7 @@ export class WeightedRoundRobinWorkerChoiceStrategy<
     Response = unknown
   >
   extends AbstractWorkerChoiceStrategy<Worker, Data, Response>
-  implements IWorkerChoiceStrategy<Worker, Data, Response> {
+  implements IWorkerChoiceStrategy {
   /** @inheritDoc */
   public readonly requiredStatistics: RequiredStatistics = {
     runTime: true,
index 3fbf5e2360cb8fb15c3a16b926ae2c5fac906f5b..66aafad6bf89b0164d2fab5f89c5aca0a4bea0c5 100644 (file)
@@ -26,7 +26,7 @@ export class WorkerChoiceStrategyContext<
 > {
   private readonly workerChoiceStrategies: Map<
   WorkerChoiceStrategy,
-  IWorkerChoiceStrategy<Worker, Data, Response>
+  IWorkerChoiceStrategy
   >
 
   /**
@@ -38,13 +38,12 @@ export class WorkerChoiceStrategyContext<
    */
   public constructor (
     pool: IPoolInternal<Worker, Data, Response>,
-    private readonly createWorkerCallback: () => number,
     private workerChoiceStrategyType: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
   ) {
     this.execute.bind(this)
     this.workerChoiceStrategies = new Map<
     WorkerChoiceStrategy,
-    IWorkerChoiceStrategy<Worker, Data, Response>
+    IWorkerChoiceStrategy
     >([
       [
         WorkerChoiceStrategies.ROUND_ROBIN,
@@ -78,7 +77,7 @@ export class WorkerChoiceStrategyContext<
     return (
       this.workerChoiceStrategies.get(
         this.workerChoiceStrategyType
-      ) as IWorkerChoiceStrategy<Worker, Data, Response>
+      ) as IWorkerChoiceStrategy
     ).requiredStatistics
   }
 
@@ -103,17 +102,11 @@ export class WorkerChoiceStrategyContext<
    * @returns The key of the chosen one.
    */
   public execute (): number {
-    const workerChoiceStrategy = this.workerChoiceStrategies.get(
-      this.workerChoiceStrategyType
-    ) as IWorkerChoiceStrategy<Worker, Data, Response>
-    if (
-      workerChoiceStrategy.isDynamicPool &&
-      !workerChoiceStrategy.pool.full &&
-      workerChoiceStrategy.pool.findFreeWorkerKey() === -1
-    ) {
-      return this.createWorkerCallback()
-    }
-    return workerChoiceStrategy.choose()
+    return (
+      this.workerChoiceStrategies.get(
+        this.workerChoiceStrategyType
+      ) as IWorkerChoiceStrategy
+    ).choose()
   }
 
   /**
@@ -126,7 +119,7 @@ export class WorkerChoiceStrategyContext<
     return (
       this.workerChoiceStrategies.get(
         this.workerChoiceStrategyType
-      ) as IWorkerChoiceStrategy<Worker, Data, Response>
+      ) as IWorkerChoiceStrategy
     ).remove(workerKey)
   }
 }