build(deps-dev): apply updates
[poolifier.git] / src / pools / abstract-pool.ts
index 2c4fdf5a99f8e3ce2accd39311caa5e8e776a737..712de0b7da4c38c2808e1be61da7fced8e372da0 100644 (file)
@@ -9,7 +9,7 @@ import type {
   MessageValue,
   PromiseResponseWrapper,
   Task,
-  TaskFunctionProperties
+  TaskFunctionProperties,
 } from '../utility-types.js'
 import {
   average,
@@ -23,11 +23,11 @@ import {
   median,
   min,
   round,
-  sleep
+  sleep,
 } from '../utils.js'
 import type {
   TaskFunction,
-  TaskFunctionObject
+  TaskFunctionObject,
 } from '../worker/task-functions.js'
 import { KillBehaviors } from '../worker/worker-options.js'
 import {
@@ -37,13 +37,13 @@ import {
   type PoolOptions,
   type PoolType,
   PoolTypes,
-  type TasksQueueOptions
+  type TasksQueueOptions,
 } from './pool.js'
 import {
   Measurements,
   WorkerChoiceStrategies,
   type WorkerChoiceStrategy,
-  type WorkerChoiceStrategyOptions
+  type WorkerChoiceStrategyOptions,
 } from './selection-strategies/selection-strategies-types.js'
 import { WorkerChoiceStrategiesContext } from './selection-strategies/worker-choice-strategies-context.js'
 import {
@@ -56,7 +56,7 @@ import {
   updateRunTimeWorkerUsage,
   updateTaskStatisticsWorkerUsage,
   updateWaitTimeWorkerUsage,
-  waitWorkerNodeEvents
+  waitWorkerNodeEvents,
 } from './utils.js'
 import { version } from './version.js'
 import type {
@@ -64,13 +64,12 @@ import type {
   IWorkerNode,
   WorkerInfo,
   WorkerNodeEventDetail,
-  WorkerType
+  WorkerType,
 } from './worker.js'
 import { WorkerNode } from './worker-node.js'
 
 /**
  * Base class that implements some shared logic for all poolifier pools.
- *
  * @typeParam Worker - Type of worker which manages this pool.
  * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
  * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
@@ -81,7 +80,7 @@ export abstract class AbstractPool<
   Response = unknown
 > implements IPool<Worker, Data, Response> {
   /** @inheritDoc */
-  public readonly workerNodes: Array<IWorkerNode<Worker, Data>> = []
+  public readonly workerNodes: IWorkerNode<Worker, Data>[] = []
 
   /** @inheritDoc */
   public emitter?: EventEmitterAsyncResource
@@ -95,19 +94,19 @@ export abstract class AbstractPool<
    */
   protected promiseResponseMap: Map<
     `${string}-${string}-${string}-${string}-${string}`,
-  PromiseResponseWrapper<Response>
+    PromiseResponseWrapper<Response>
   > = new Map<
     `${string}-${string}-${string}-${string}-${string}`,
     PromiseResponseWrapper<Response>
-    >()
+  >()
 
   /**
    * Worker choice strategies context referencing worker choice algorithms implementation.
    */
   protected workerChoiceStrategiesContext?: WorkerChoiceStrategiesContext<
-  Worker,
-  Data,
-  Response
+    Worker,
+    Data,
+    Response
   >
 
   /**
@@ -116,8 +115,8 @@ export abstract class AbstractPool<
    * - `value`: The task function object.
    */
   private readonly taskFunctions: Map<
-  string,
-  TaskFunctionObject<Data, Response>
+    string,
+    TaskFunctionObject<Data, Response>
   >
 
   /**
@@ -147,7 +146,6 @@ export abstract class AbstractPool<
 
   /**
    * Constructs a new poolifier pool.
-   *
    * @param minimumNumberOfWorkers - Minimum number of workers that this pool manages.
    * @param filePath - Path to the worker file.
    * @param opts - Options for the pool.
@@ -177,9 +175,9 @@ export abstract class AbstractPool<
       this.initEventEmitter()
     }
     this.workerChoiceStrategiesContext = new WorkerChoiceStrategiesContext<
-    Worker,
-    Data,
-    Response
+      Worker,
+      Data,
+      Response
     >(
       this,
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
@@ -289,7 +287,7 @@ export abstract class AbstractPool<
 
   private initEventEmitter (): void {
     this.emitter = new EventEmitterAsyncResource({
-      name: `poolifier:${this.type}-${this.worker}-pool`
+      name: `poolifier:${this.type}-${this.worker}-pool`,
     })
   }
 
@@ -310,7 +308,7 @@ export abstract class AbstractPool<
         .runTime.aggregate === true &&
         this.workerChoiceStrategiesContext.getTaskStatisticsRequirements()
           .waitTime.aggregate && {
-        utilization: round(this.utilization)
+        utilization: round(this.utilization),
       }),
       workerNodes: this.workerNodes.length,
       idleWorkerNodes: this.workerNodes.reduce(
@@ -325,7 +323,7 @@ export abstract class AbstractPool<
           (accumulator, workerNode) =>
             workerNode.info.stealing ? accumulator + 1 : accumulator,
           0
-        )
+        ),
       }),
       busyWorkerNodes: this.workerNodes.reduce(
         (accumulator, _, workerNodeKey) =>
@@ -347,24 +345,24 @@ export abstract class AbstractPool<
           (accumulator, workerNode) =>
             accumulator + workerNode.usage.tasks.queued,
           0
-        )
+        ),
       }),
       ...(this.opts.enableTasksQueue === true && {
         maxQueuedTasks: this.workerNodes.reduce(
           (accumulator, workerNode) =>
             accumulator + (workerNode.usage.tasks.maxQueued ?? 0),
           0
-        )
+        ),
       }),
       ...(this.opts.enableTasksQueue === true && {
-        backPressure: this.hasBackPressure()
+        backPressure: this.hasBackPressure(),
       }),
       ...(this.opts.enableTasksQueue === true && {
         stolenTasks: this.workerNodes.reduce(
           (accumulator, workerNode) =>
             accumulator + workerNode.usage.tasks.stolen,
           0
-        )
+        ),
       }),
       failedTasks: this.workerNodes.reduce(
         (accumulator, workerNode) =>
@@ -402,7 +400,7 @@ export abstract class AbstractPool<
                   []
                 )
               )
-            )
+            ),
           }),
           ...(this.workerChoiceStrategiesContext.getTaskStatisticsRequirements()
             .runTime.median && {
@@ -416,9 +414,9 @@ export abstract class AbstractPool<
                   []
                 )
               )
-            )
-          })
-        }
+            ),
+          }),
+        },
       }),
       ...(this.workerChoiceStrategiesContext?.getTaskStatisticsRequirements()
         .waitTime.aggregate === true && {
@@ -451,7 +449,7 @@ export abstract class AbstractPool<
                   []
                 )
               )
-            )
+            ),
           }),
           ...(this.workerChoiceStrategiesContext.getTaskStatisticsRequirements()
             .waitTime.median && {
@@ -465,9 +463,9 @@ export abstract class AbstractPool<
                   []
                 )
               )
-            )
-          })
-        }
+            ),
+          }),
+        },
       }),
       ...(this.workerChoiceStrategiesContext?.getTaskStatisticsRequirements()
         .elu.aggregate === true && {
@@ -503,7 +501,7 @@ export abstract class AbstractPool<
                     []
                   )
                 )
-              )
+              ),
             }),
             ...(this.workerChoiceStrategiesContext.getTaskStatisticsRequirements()
               .elu.median && {
@@ -517,8 +515,8 @@ export abstract class AbstractPool<
                     []
                   )
                 )
-              )
-            })
+              ),
+            }),
           },
           active: {
             minimum: round(
@@ -551,7 +549,7 @@ export abstract class AbstractPool<
                     []
                   )
                 )
-              )
+              ),
             }),
             ...(this.workerChoiceStrategiesContext.getTaskStatisticsRequirements()
               .elu.median && {
@@ -565,8 +563,8 @@ export abstract class AbstractPool<
                     []
                   )
                 )
-              )
-            })
+              ),
+            }),
           },
           utilization: {
             average: round(
@@ -582,15 +580,16 @@ export abstract class AbstractPool<
                   workerNode => workerNode.usage.elu.utilization ?? 0
                 )
               )
-            )
-          }
-        }
-      })
+            ),
+          },
+        },
+      }),
     }
   }
 
   /**
-   * The pool readiness boolean status.
+   * Whether the pool is ready or not.
+   * @returns The pool readiness boolean status.
    */
   private get ready (): boolean {
     if (this.empty) {
@@ -608,7 +607,8 @@ export abstract class AbstractPool<
   }
 
   /**
-   * The pool emptiness boolean status.
+   * Whether the pool is empty or not.
+   * @returns The pool emptiness boolean status.
    */
   protected get empty (): boolean {
     return this.minimumNumberOfWorkers === 0 && this.workerNodes.length === 0
@@ -616,7 +616,6 @@ export abstract class AbstractPool<
 
   /**
    * The approximate pool utilization.
-   *
    * @returns The pool utilization.
    */
   private get utilization (): number {
@@ -653,7 +652,6 @@ export abstract class AbstractPool<
 
   /**
    * Checks if the worker id sent in the received message from a worker is valid.
-   *
    * @param message - The received message.
    * @throws {@link https://nodejs.org/api/errors.html#class-error} If the worker id is invalid.
    */
@@ -662,14 +660,13 @@ export abstract class AbstractPool<
       throw new Error('Worker message received without worker id')
     } else if (this.getWorkerNodeKeyByWorkerId(message.workerId) === -1) {
       throw new Error(
-        `Worker message received from unknown worker '${message.workerId}'`
+        `Worker message received from unknown worker '${message.workerId.toString()}'`
       )
     }
   }
 
   /**
    * Gets the worker node key given its worker id.
-   *
    * @param workerId - The worker id.
    * @returns The worker node key if the worker id is found in the pool worker nodes, `-1` otherwise.
    */
@@ -780,7 +777,7 @@ export abstract class AbstractPool<
       ...getDefaultTasksQueueOptions(
         this.maximumNumberOfWorkers ?? this.minimumNumberOfWorkers
       ),
-      ...tasksQueueOptions
+      ...tasksQueueOptions,
     }
   }
 
@@ -825,8 +822,7 @@ export abstract class AbstractPool<
 
   /**
    * Whether the pool is full or not.
-   *
-   * The pool filling boolean status.
+   * @returns The pool fullness boolean status.
    */
   protected get full (): boolean {
     return (
@@ -837,14 +833,12 @@ export abstract class AbstractPool<
 
   /**
    * Whether the pool is busy or not.
-   *
-   * The pool busyness boolean status.
+   * @returns The pool busyness boolean status.
    */
   protected abstract get busy (): boolean
 
   /**
    * Whether worker nodes are executing concurrently their tasks quota or not.
-   *
    * @returns Worker nodes busyness boolean status.
    */
   protected internalBusy (): boolean {
@@ -897,7 +891,11 @@ export abstract class AbstractPool<
           } else {
             reject(
               new Error(
-                `Task function operation '${message.taskFunctionOperation}' failed on worker ${message.workerId} with error: '${message.workerError?.message}'`
+                // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+                `Task function operation '${message.taskFunctionOperation?.toString()}' failed on worker ${message.workerId?.toString()} with error: '${
+                  // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+                  message.workerError?.message
+                }'`
               )
             )
           }
@@ -945,7 +943,9 @@ export abstract class AbstractPool<
                 new Error(
                   `Task function operation '${
                     message.taskFunctionOperation as string
-                  }' failed on worker ${errorResponse?.workerId} with error: '${
+                    // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+                  }' failed on worker ${errorResponse?.workerId?.toString()} with error: '${
+                    // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
                     errorResponse?.workerError?.message
                   }'`
                 )
@@ -997,7 +997,7 @@ export abstract class AbstractPool<
     const opResult = await this.sendTaskFunctionOperationToWorkers({
       taskFunctionOperation: 'add',
       taskFunctionProperties: buildTaskFunctionProperties(name, fn),
-      taskFunction: fn.taskFunction.toString()
+      taskFunction: fn.taskFunction.toString(),
     })
     this.taskFunctions.set(name, fn)
     this.workerChoiceStrategiesContext?.syncWorkerChoiceStrategies(
@@ -1021,7 +1021,7 @@ export abstract class AbstractPool<
       taskFunctionProperties: buildTaskFunctionProperties(
         name,
         this.taskFunctions.get(name)
-      )
+      ),
     })
     for (const workerNode of this.workerNodes) {
       workerNode.deleteTaskFunctionWorkerUsage(name)
@@ -1051,7 +1051,6 @@ export abstract class AbstractPool<
 
   /**
    * Gets task function worker choice strategy, if any.
-   *
    * @param name - The task function name.
    * @returns The task function worker choice strategy if the task function worker choice strategy is defined, `undefined` otherwise.
    */
@@ -1071,7 +1070,6 @@ export abstract class AbstractPool<
 
   /**
    * Gets worker node task function worker choice strategy, if any.
-   *
    * @param workerNodeKey - The worker node key.
    * @param name - The task function name.
    * @returns The worker node task function worker choice strategy if the worker node task function worker choice strategy is defined, `undefined` otherwise.
@@ -1096,7 +1094,6 @@ export abstract class AbstractPool<
 
   /**
    * Gets worker node task function priority, if any.
-   *
    * @param workerNodeKey - The worker node key.
    * @param name - The task function name.
    * @returns The worker node task function priority if the worker node task function priority is defined, `undefined` otherwise.
@@ -1121,7 +1118,6 @@ export abstract class AbstractPool<
 
   /**
    * Gets the worker choice strategies registered in this pool.
-   *
    * @returns The worker choice strategies.
    */
   private readonly getWorkerChoiceStrategies =
@@ -1136,7 +1132,7 @@ export abstract class AbstractPool<
           )
           .filter(
             (strategy: WorkerChoiceStrategy | undefined) => strategy != null
-          ) as WorkerChoiceStrategy[])
+          ) as WorkerChoiceStrategy[]),
       ])
     }
 
@@ -1147,7 +1143,7 @@ export abstract class AbstractPool<
       taskFunctionProperties: buildTaskFunctionProperties(
         name,
         this.taskFunctions.get(name)
-      )
+      ),
     })
   }
 
@@ -1195,7 +1191,6 @@ export abstract class AbstractPool<
       const workerNodeKey = this.chooseWorkerNode(name)
       const task: Task<Data> = {
         name: name ?? DEFAULT_TASK_NAME,
-        // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
         data: data ?? ({} as Data),
         priority: this.getWorkerNodeTaskFunctionPriority(workerNodeKey, name),
         strategy: this.getWorkerNodeTaskFunctionWorkerChoiceStrategy(
@@ -1204,7 +1199,7 @@ export abstract class AbstractPool<
         ),
         transferList,
         timestamp,
-        taskId: randomUUID()
+        taskId: randomUUID(),
       }
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       this.promiseResponseMap.set(task.taskId!, {
@@ -1214,9 +1209,9 @@ export abstract class AbstractPool<
         ...(this.emitter != null && {
           asyncResource: new AsyncResource('poolifier:task', {
             triggerAsyncId: this.emitter.asyncId,
-            requireManualDestroy: true
-          })
-        })
+            requireManualDestroy: true,
+          }),
+        }),
       })
       if (
         this.opts.enableTasksQueue === false ||
@@ -1230,10 +1225,36 @@ export abstract class AbstractPool<
     })
   }
 
+
+  /** @inheritDoc */
+  public mapExecute (
+    data: Iterable<Data>,
+    name?: string,
+    transferList?: readonly TransferListItem[]
+  ): Promise<Response[]> {
+    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+    if (data == null) {
+      throw new TypeError('data argument must be a defined iterable')
+    }
+    if (typeof data[Symbol.iterator] !== 'function') {
+      throw new TypeError('data argument must be an iterable')
+    }
+    if (!Array.isArray(data)) {
+      data = [...data]
+    }
+    return Promise.all(
+      (data as Data[]).map(data => this.execute(data, name, transferList))
+    )
+  }
+
   /**
    * Starts the minimum number of workers.
+   * @param initWorkerNodeUsage - Whether to initialize the worker node usage or not. @defaultValue false
    */
   private startMinimumNumberOfWorkers (initWorkerNodeUsage = false): void {
+    if (this.minimumNumberOfWorkers === 0) {
+      return
+    }
     this.startingMinimumNumberOfWorkers = true
     while (
       this.workerNodes.reduce(
@@ -1306,7 +1327,8 @@ export abstract class AbstractPool<
         } else if (message.kill === 'failure') {
           reject(
             new Error(
-              `Kill message handling failed on worker ${message.workerId}`
+              // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+              `Kill message handling failed on worker ${message.workerId?.toString()}`
             )
           )
         }
@@ -1319,7 +1341,6 @@ export abstract class AbstractPool<
 
   /**
    * Terminates the worker node given its worker node key.
-   *
    * @param workerNodeKey - The worker node key.
    */
   protected async destroyWorkerNode (workerNodeKey: number): Promise<void> {
@@ -1342,8 +1363,6 @@ export abstract class AbstractPool<
   /**
    * Setup hook to execute code before worker nodes are created in the abstract constructor.
    * Can be overridden.
-   *
-   * @virtual
    */
   protected setupHook (): void {
     /* Intentionally empty */
@@ -1351,7 +1370,6 @@ export abstract class AbstractPool<
 
   /**
    * Returns whether the worker is the main worker or not.
-   *
    * @returns `true` if the worker is the main worker, `false` otherwise.
    */
   protected abstract isMain (): boolean
@@ -1359,7 +1377,6 @@ export abstract class AbstractPool<
   /**
    * Hook executed before the worker task execution.
    * Can be overridden.
-   *
    * @param workerNodeKey - The worker node key.
    * @param task - The task to execute.
    */
@@ -1400,7 +1417,6 @@ export abstract class AbstractPool<
   /**
    * Hook executed after the worker task execution.
    * Can be overridden.
-   *
    * @param workerNodeKey - The worker node key.
    * @param message - The received message.
    */
@@ -1457,7 +1473,6 @@ export abstract class AbstractPool<
 
   /**
    * Whether the worker node shall update its task function worker usage or not.
-   *
    * @param workerNodeKey - The worker node key.
    * @returns `true` if the worker node shall update its task function worker usage, `false` otherwise.
    */
@@ -1472,7 +1487,6 @@ export abstract class AbstractPool<
 
   /**
    * Chooses a worker node for the next task.
-   *
    * @param name - The task function name.
    * @returns The chosen worker node key.
    */
@@ -1494,14 +1508,12 @@ export abstract class AbstractPool<
 
   /**
    * Conditions for dynamic worker creation.
-   *
    * @returns Whether to create a dynamic worker or not.
    */
   protected abstract shallCreateDynamicWorker (): boolean
 
   /**
    * Sends a message to worker given its worker node key.
-   *
    * @param workerNodeKey - The worker node key.
    * @param message - The message.
    * @param transferList - The optional array of transferable objects.
@@ -1514,7 +1526,6 @@ export abstract class AbstractPool<
 
   /**
    * Initializes the worker node usage with sensible default values gathered during runtime.
-   *
    * @param workerNode - The worker node.
    */
   private initWorkerNodeUsage (workerNode: IWorkerNode<Worker, Data>): void {
@@ -1555,7 +1566,6 @@ export abstract class AbstractPool<
 
   /**
    * Creates a new, completely set up worker node.
-   *
    * @returns New, completely set up worker node key.
    */
   protected createAndSetupWorkerNode (): number {
@@ -1619,7 +1629,6 @@ export abstract class AbstractPool<
 
   /**
    * Creates a new, completely set up dynamic worker node.
-   *
    * @returns New, completely set up dynamic worker node key.
    */
   protected createAndSetupDynamicWorkerNode (): number {
@@ -1651,7 +1660,7 @@ export abstract class AbstractPool<
       }
     })
     this.sendToWorker(workerNodeKey, {
-      checkActive: true
+      checkActive: true,
     })
     if (this.taskFunctions.size > 0) {
       for (const [taskFunctionName, taskFunctionObject] of this.taskFunctions) {
@@ -1661,7 +1670,7 @@ export abstract class AbstractPool<
             taskFunctionName,
             taskFunctionObject
           ),
-          taskFunction: taskFunctionObject.taskFunction.toString()
+          taskFunction: taskFunctionObject.taskFunction.toString(),
         }).catch((error: unknown) => {
           this.emitter?.emit(PoolEvents.error, error)
         })
@@ -1684,7 +1693,6 @@ export abstract class AbstractPool<
 
   /**
    * Registers a listener callback on the worker given its worker node key.
-   *
    * @param workerNodeKey - The worker node key.
    * @param listener - The message listener callback.
    */
@@ -1697,7 +1705,6 @@ export abstract class AbstractPool<
 
   /**
    * Registers once a listener callback on the worker given its worker node key.
-   *
    * @param workerNodeKey - The worker node key.
    * @param listener - The message listener callback.
    */
@@ -1710,7 +1717,6 @@ export abstract class AbstractPool<
 
   /**
    * Deregisters a listener callback on the worker given its worker node key.
-   *
    * @param workerNodeKey - The worker node key.
    * @param listener - The message listener callback.
    */
@@ -1724,7 +1730,6 @@ export abstract class AbstractPool<
   /**
    * Method hooked up after a worker node has been newly created.
    * Can be overridden.
-   *
    * @param workerNodeKey - The newly created worker node key.
    */
   protected afterWorkerNodeSetup (workerNodeKey: number): void {
@@ -1755,14 +1760,12 @@ export abstract class AbstractPool<
 
   /**
    * Sends the startup message to worker given its worker node key.
-   *
    * @param workerNodeKey - The worker node key.
    */
   protected abstract sendStartupMessageToWorker (workerNodeKey: number): void
 
   /**
    * Sends the statistics message to worker given its worker node key.
-   *
    * @param workerNodeKey - The worker node key.
    */
   private sendStatisticsMessageToWorker (workerNodeKey: number): void {
@@ -1773,8 +1776,8 @@ export abstract class AbstractPool<
             .runTime.aggregate ?? false,
         elu:
           this.workerChoiceStrategiesContext?.getTaskStatisticsRequirements()
-            .elu.aggregate ?? false
-      }
+            .elu.aggregate ?? false,
+      },
     })
   }
 
@@ -1895,7 +1898,7 @@ export abstract class AbstractPool<
     const workerInfo = this.getWorkerInfo(workerNodeKey)
     if (workerInfo == null) {
       throw new Error(
-        `Worker node with key '${workerNodeKey}' not found in pool`
+        `Worker node with key '${workerNodeKey.toString()}' not found in pool`
       )
     }
     if (
@@ -2011,7 +2014,7 @@ export abstract class AbstractPool<
         const workerInfo = this.getWorkerInfo(workerNodeKey)
         if (workerInfo == null) {
           throw new Error(
-            `Worker node with key '${workerNodeKey}' not found in pool`
+            `Worker node with key '${workerNodeKey.toString()}' not found in pool`
           )
         }
         workerInfo.stealing = true
@@ -2025,8 +2028,15 @@ export abstract class AbstractPool<
     }
   }
 
+  private setTasksQueuePriority (workerNodeKey: number): void {
+    this.workerNodes[workerNodeKey].setTasksQueuePriority(
+      this.getTasksQueuePriority()
+    )
+  }
+
   /**
    * This method is the message listener registered on each worker.
+   * @param message - The message received from the worker.
    */
   protected readonly workerMessageListener = (
     message: MessageValue<Response>
@@ -2043,6 +2053,7 @@ export abstract class AbstractPool<
       if (workerInfo != null) {
         workerInfo.taskFunctionsProperties = taskFunctionsProperties
         this.sendStatisticsMessageToWorker(workerNodeKey)
+        this.setTasksQueuePriority(workerNodeKey)
       }
     } else if (taskId != null) {
       // Task execution response received from worker
@@ -2060,13 +2071,15 @@ export abstract class AbstractPool<
   private handleWorkerReadyResponse (message: MessageValue<Response>): void {
     const { workerId, ready, taskFunctionsProperties } = message
     if (ready == null || !ready) {
-      throw new Error(`Worker ${workerId} failed to initialize`)
+      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+      throw new Error(`Worker ${workerId?.toString()} failed to initialize`)
     }
     const workerNodeKey = this.getWorkerNodeKeyByWorkerId(workerId)
     const workerNode = this.workerNodes[workerNodeKey]
     workerNode.info.ready = ready
     workerNode.info.taskFunctionsProperties = taskFunctionsProperties
     this.sendStatisticsMessageToWorker(workerNodeKey)
+    this.setTasksQueuePriority(workerNodeKey)
     this.checkAndEmitReadyEvent()
   }
 
@@ -2120,7 +2133,7 @@ export abstract class AbstractPool<
         ) {
           workerNode.emit('idle', {
             workerId,
-            workerNodeKey
+            workerNodeKey,
           })
         }
       }
@@ -2146,7 +2159,6 @@ export abstract class AbstractPool<
 
   /**
    * Gets the worker information given its worker node key.
-   *
    * @param workerNodeKey - The worker node key.
    * @returns The worker information.
    */
@@ -2154,9 +2166,14 @@ export abstract class AbstractPool<
     return this.workerNodes[workerNodeKey]?.info
   }
 
+  private getTasksQueuePriority (): boolean {
+    return this.listTaskFunctionsProperties().some(
+      taskFunctionProperties => taskFunctionProperties.priority != null
+    )
+  }
+
   /**
    * Creates a worker node.
-   *
    * @returns The created worker node.
    */
   private createWorkerNode (): IWorkerNode<Worker, Data> {
@@ -2171,7 +2188,8 @@ export abstract class AbstractPool<
           getDefaultTasksQueueOptions(
             this.maximumNumberOfWorkers ?? this.minimumNumberOfWorkers
           ).size,
-        tasksQueueBucketSize: defaultBucketSize
+        tasksQueueBucketSize: defaultBucketSize,
+        tasksQueuePriority: this.getTasksQueuePriority(),
       }
     )
     // Flag the worker node as ready at pool startup.
@@ -2183,7 +2201,6 @@ export abstract class AbstractPool<
 
   /**
    * Adds the given worker node in the pool worker nodes.
-   *
    * @param workerNode - The worker node.
    * @returns The added worker node key.
    * @throws {@link https://nodejs.org/api/errors.html#class-error} If the added worker node is not found.
@@ -2206,7 +2223,6 @@ export abstract class AbstractPool<
 
   /**
    * Removes the worker node from the pool worker nodes.
-   *
    * @param workerNode - The worker node.
    */
   private removeWorkerNode (workerNode: IWorkerNode<Worker, Data>): void {
@@ -2236,7 +2252,6 @@ export abstract class AbstractPool<
 
   /**
    * Executes the given task on the worker given its worker node key.
-   *
    * @param workerNodeKey - The worker node key.
    * @param task - The task to execute.
    */