Fix eslint configuration
[poolifier.git] / src / pools / selection-strategies.ts
index f86442b0f5fc836fd9cacf77333d1bab69f1fae2..f1c20befd6b709784f08f5fe339709d2bf3b1e3d 100644 (file)
@@ -1,6 +1,6 @@
-import { isKillBehavior, KillBehaviors } from '../worker/worker-options'
 import type { IWorker } from './abstract-pool'
 import type { IPoolInternal } from './pool-internal'
+import { PoolType } from './pool-internal'
 
 /**
  * Enumeration of worker choice strategies.
@@ -60,7 +60,7 @@ class RoundRobinWorkerChoiceStrategy<Worker extends IWorker, Data, Response>
   public choose (): Worker {
     const chosenWorker = this.pool.workers[this.nextWorkerIndex]
     this.nextWorkerIndex =
-      this.pool.workers.length - 1 === this.nextWorkerIndex
+      this.nextWorkerIndex === this.pool.workers.length - 1
         ? 0
         : this.nextWorkerIndex + 1
     return chosenWorker
@@ -90,7 +90,7 @@ class LessRecentlyUsedWorkerChoiceStrategy<
 
   /** @inheritdoc */
   public choose (): Worker {
-    const isPoolDynamic = this.pool.dynamic
+    const isPoolDynamic = this.pool.type === PoolType.DYNAMIC
     let minNumberOfTasks = Infinity
     // A worker is always found because it picks the one with fewer tasks
     let lessRecentlyUsedWorker!: Worker
@@ -98,8 +98,8 @@ class LessRecentlyUsedWorkerChoiceStrategy<
       if (!isPoolDynamic && numberOfTasks === 0) {
         return worker
       } else if (numberOfTasks < minNumberOfTasks) {
-        minNumberOfTasks = numberOfTasks
         lessRecentlyUsedWorker = worker
+        minNumberOfTasks = numberOfTasks
       }
     }
     return lessRecentlyUsedWorker
@@ -121,10 +121,12 @@ class DynamicPoolWorkerChoiceStrategy<Worker extends IWorker, Data, Response>
    * Constructs a worker choice strategy for dynamical pools.
    *
    * @param pool The pool instance.
-   * @param workerChoiceStrategy The worker choice strategy when the pull is full.
+   * @param createDynamicallyWorkerCallback The worker creation callback for dynamic pool.
+   * @param workerChoiceStrategy The worker choice strategy when the pull is busy.
    */
   public constructor (
     private readonly pool: IPoolInternal<Worker, Data, Response>,
+    private createDynamicallyWorkerCallback: () => Worker,
     workerChoiceStrategy: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
   ) {
     this.workerChoiceStrategy = SelectionStrategiesUtils.getWorkerChoiceStrategy(
@@ -135,31 +137,17 @@ class DynamicPoolWorkerChoiceStrategy<Worker extends IWorker, Data, Response>
 
   /** @inheritdoc */
   public choose (): Worker {
-    const freeWorker = SelectionStrategiesUtils.findFreeWorkerBasedOnTasks(
-      this.pool
-    )
-    if (freeWorker) {
-      return freeWorker
+    const freeTaskMapEntry = this.pool.findFreeTasksMapEntry()
+    if (freeTaskMapEntry) {
+      return freeTaskMapEntry[0]
     }
 
-    if (this.pool.workers.length === this.pool.max) {
-      this.pool.emitter.emit('FullPool')
+    if (this.pool.busy) {
       return this.workerChoiceStrategy.choose()
     }
 
     // All workers are busy, create a new worker
-    const workerCreated = this.pool.createAndSetupWorker()
-    this.pool.registerWorkerMessageListener(workerCreated, message => {
-      const tasksInProgress = this.pool.tasks.get(workerCreated)
-      if (
-        isKillBehavior(KillBehaviors.HARD, message.kill) ||
-        tasksInProgress === 0
-      ) {
-        // Kill received from the worker, means that no new tasks are submitted to that worker for a while ( > maxInactiveTime)
-        void this.pool.destroyWorker(workerCreated)
-      }
-    })
-    return workerCreated
+    return this.createDynamicallyWorkerCallback()
   }
 }
 
@@ -182,10 +170,12 @@ export class WorkerChoiceStrategyContext<
    * Worker choice strategy context constructor.
    *
    * @param pool The pool instance.
+   * @param createDynamicallyWorkerCallback The worker creation callback for dynamic pool.
    * @param workerChoiceStrategy The worker choice strategy.
    */
   public constructor (
     private readonly pool: IPoolInternal<Worker, Data, Response>,
+    private createDynamicallyWorkerCallback: () => Worker,
     workerChoiceStrategy: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
   ) {
     this.setWorkerChoiceStrategy(workerChoiceStrategy)
@@ -200,9 +190,10 @@ export class WorkerChoiceStrategyContext<
   private getPoolWorkerChoiceStrategy (
     workerChoiceStrategy: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
   ): IWorkerChoiceStrategy<Worker> {
-    if (this.pool.dynamic) {
+    if (this.pool.type === PoolType.DYNAMIC) {
       return new DynamicPoolWorkerChoiceStrategy(
         this.pool,
+        this.createDynamicallyWorkerCallback,
         workerChoiceStrategy
       )
     }
@@ -236,33 +227,9 @@ export class WorkerChoiceStrategyContext<
 }
 
 /**
- * Worker selection strategies helpers.
+ * Worker selection strategies helpers class.
  */
 class SelectionStrategiesUtils {
-  /**
-   * Find a free worker based on number of tasks the worker has applied.
-   *
-   * If a worker was found that has `0` tasks, it is detected as free and will be returned.
-   *
-   * If no free worker was found, `null` will be returned.
-   *
-   * @param pool The pool instance.
-   * @returns A free worker if there was one, otherwise `null`.
-   */
-  public static findFreeWorkerBasedOnTasks<
-    Worker extends IWorker,
-    Data,
-    Response
-  > (pool: IPoolInternal<Worker, Data, Response>): Worker | null {
-    for (const [worker, numberOfTasks] of pool.tasks) {
-      if (numberOfTasks === 0) {
-        // A worker is free, use it
-        return worker
-      }
-    }
-    return null
-  }
-
   /**
    * Get the worker choice strategy instance.
    *
@@ -285,6 +252,7 @@ class SelectionStrategiesUtils {
         return new LessRecentlyUsedWorkerChoiceStrategy(pool)
       default:
         throw new Error(
+          // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
           `Worker choice strategy '${workerChoiceStrategy}' not found`
         )
     }