+
+ /**
+ * This function is the listener registered for each worker.
+ *
+ * @returns The listener function to execute when a message is received from a worker.
+ */
+ protected workerListener (): (message: MessageValue<Response>) => void {
+ return message => {
+ if (message.id != null) {
+ // Task response received
+ const promiseResponse = this.promiseResponseMap.get(message.id)
+ if (promiseResponse != null) {
+ if (message.error != null) {
+ promiseResponse.reject(message.error)
+ } else {
+ promiseResponse.resolve(message.data as Response)
+ }
+ this.afterPromiseResponseHook(promiseResponse.worker, message)
+ this.promiseResponseMap.delete(message.id)
+ }
+ }
+ }
+ }
+
+ private async internalExecute (
+ workerNodeKey: number,
+ workerNode: WorkerNode<Worker, Data>,
+ task: Task<Data>
+ ): Promise<Response> {
+ this.beforePromiseResponseHook(workerNodeKey)
+ return await new Promise<Response>((resolve, reject) => {
+ this.promiseResponseMap.set(task.id, {
+ resolve,
+ reject,
+ worker: workerNode.worker
+ })
+ })
+ }
+
+ private checkAndEmitBusy (): void {
+ if (this.opts.enableEvents === true && this.busy) {
+ this.emitter?.emit(PoolEvents.busy)
+ }
+ }
+
+ private checkAndEmitFull (): void {
+ if (
+ this.type === PoolType.DYNAMIC &&
+ this.opts.enableEvents === true &&
+ this.full
+ ) {
+ this.emitter?.emit(PoolEvents.full)
+ }
+ }
+
+ /**
+ * Gets the given worker its tasks usage in the pool.
+ *
+ * @param worker - The worker.
+ * @returns The worker tasks usage.
+ */
+ private getWorkerTasksUsage (worker: Worker): TasksUsage | undefined {
+ const workerNodeKey = this.getWorkerNodeKey(worker)
+ if (workerNodeKey !== -1) {
+ return this.workerNodes[workerNodeKey].tasksUsage
+ }
+ throw new Error('Worker could not be found in the pool worker nodes')
+ }
+
+ /**
+ * Pushes the given worker in the pool worker nodes.
+ *
+ * @param worker - The worker.
+ * @returns The worker nodes length.
+ */
+ private pushWorkerNode (worker: Worker): number {
+ return this.workerNodes.push({
+ worker,
+ tasksUsage: {
+ run: 0,
+ running: 0,
+ runTime: 0,
+ runTimeHistory: new CircularArray(),
+ avgRunTime: 0,
+ medRunTime: 0,
+ error: 0
+ },
+ tasksQueue: []
+ })
+ }
+
+ /**
+ * Sets the given worker in the pool worker nodes.
+ *
+ * @param workerNodeKey - The worker node key.
+ * @param worker - The worker.
+ * @param tasksUsage - The worker tasks usage.
+ * @param tasksQueue - The worker task queue.
+ */
+ private setWorkerNode (
+ workerNodeKey: number,
+ worker: Worker,
+ tasksUsage: TasksUsage,
+ tasksQueue: Array<Task<Data>>
+ ): void {
+ this.workerNodes[workerNodeKey] = {
+ worker,
+ tasksUsage,
+ tasksQueue
+ }
+ }
+
+ /**
+ * Removes the given worker from the pool worker nodes.
+ *
+ * @param worker - The worker.
+ */
+ protected removeWorkerNode (worker: Worker): void {
+ const workerNodeKey = this.getWorkerNodeKey(worker)
+ this.workerNodes.splice(workerNodeKey, 1)
+ this.workerChoiceStrategyContext.remove(workerNodeKey)
+ }
+
+ protected enqueueTask (workerNodeKey: number, task: Task<Data>): void {
+ this.workerNodes[workerNodeKey].tasksQueue.push(task)
+ }
+
+ protected dequeueTask (workerNodeKey: number): Task<Data> | undefined {
+ return this.workerNodes[workerNodeKey].tasksQueue.shift()
+ }
+
+ protected tasksQueueLength (workerNodeKey: number): number {
+ return this.workerNodes[workerNodeKey].tasksQueue.length
+ }