+
+ /**
+ * 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 !== undefined) {
+ const promise = this.promiseMap.get(message.id)
+ if (promise !== undefined) {
+ this.afterPromiseWorkerResponseHook(message, promise)
+ if (message.error) promise.reject(message.error)
+ else promise.resolve(message.data as Response)
+ this.promiseMap.delete(message.id)
+ }
+ }
+ }
+ }
+
+ private checkAndEmitBusy (): void {
+ if (this.opts.enableEvents === true && this.busy === true) {
+ this.emitter?.emit('busy')
+ }
+ }
+
+ /**
+ * Increases the number of tasks that the given worker has applied.
+ *
+ * @param worker Worker which running tasks is increased.
+ */
+ private increaseWorkerRunningTasks (worker: Worker): void {
+ this.stepWorkerRunningTasks(worker, 1)
+ }
+
+ /**
+ * Decreases the number of tasks that the given worker has applied.
+ *
+ * @param worker Worker which running tasks is decreased.
+ */
+ private decreaseWorkerRunningTasks (worker: Worker): void {
+ this.stepWorkerRunningTasks(worker, -1)
+ }
+
+ /**
+ * Steps the number of tasks that the given worker has applied.
+ *
+ * @param worker Worker which running tasks are stepped.
+ * @param step Number of running tasks step.
+ */
+ private stepWorkerRunningTasks (worker: Worker, step: number): void {
+ const tasksUsage = this.workersTasksUsage.get(worker)
+ if (tasksUsage !== undefined) {
+ tasksUsage.running = tasksUsage.running + step
+ this.workersTasksUsage.set(worker, tasksUsage)
+ } else {
+ throw new Error(WORKER_NOT_FOUND_TASKS_USAGE_MAP)
+ }
+ }
+
+ /**
+ * Steps the number of tasks that the given worker has run.
+ *
+ * @param worker Worker which has run tasks.
+ * @param step Number of run tasks step.
+ */
+ private stepWorkerRunTasks (worker: Worker, step: number): void {
+ const tasksUsage = this.workersTasksUsage.get(worker)
+ if (tasksUsage !== undefined) {
+ tasksUsage.run = tasksUsage.run + step
+ this.workersTasksUsage.set(worker, tasksUsage)
+ } else {
+ throw new Error(WORKER_NOT_FOUND_TASKS_USAGE_MAP)
+ }
+ }
+
+ /**
+ * Updates tasks runtime for the given worker.
+ *
+ * @param worker Worker which run the task.
+ * @param taskRunTime Worker task runtime.
+ */
+ private updateWorkerTasksRunTime (
+ worker: Worker,
+ taskRunTime: number | undefined
+ ): void {
+ if (
+ this.workerChoiceStrategyContext.getWorkerChoiceStrategy()
+ .requiredStatistics.runTime === true
+ ) {
+ const tasksUsage = this.workersTasksUsage.get(worker)
+ if (tasksUsage !== undefined) {
+ tasksUsage.runTime += taskRunTime ?? 0
+ if (tasksUsage.run !== 0) {
+ tasksUsage.avgRunTime = tasksUsage.runTime / tasksUsage.run
+ }
+ this.workersTasksUsage.set(worker, tasksUsage)
+ } else {
+ throw new Error(WORKER_NOT_FOUND_TASKS_USAGE_MAP)
+ }
+ }
+ }
+
+ /**
+ * Initializes tasks usage statistics.
+ *
+ * @param worker The worker.
+ */
+ initWorkerTasksUsage (worker: Worker): void {
+ this.workersTasksUsage.set(worker, {
+ run: 0,
+ running: 0,
+ runTime: 0,
+ avgRunTime: 0
+ })
+ }
+
+ /**
+ * Removes worker tasks usage statistics.
+ *
+ * @param worker The worker.
+ */
+ private removeWorkerTasksUsage (worker: Worker): void {
+ this.workersTasksUsage.delete(worker)
+ }
+
+ /**
+ * Resets worker tasks usage statistics.
+ *
+ * @param worker The worker.
+ */
+ private resetWorkerTasksUsage (worker: Worker): void {
+ this.removeWorkerTasksUsage(worker)
+ this.initWorkerTasksUsage(worker)
+ }