fix: ensure worker info is defined before accessing it
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 3 Jan 2024 23:09:48 +0000 (00:09 +0100)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 3 Jan 2024 23:09:48 +0000 (00:09 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
src/pools/abstract-pool.ts
src/pools/cluster/fixed.ts
src/pools/thread/fixed.ts

index 5d79cb43b09c18ea6c4f7b5fc46382822ba48a41..474115630a747fa6a83724faa6a3c1953382e7fb 100644 (file)
@@ -703,7 +703,7 @@ export abstract class AbstractPool<
         message: MessageValue<Response>
       ): void => {
         this.checkMessageWorkerId(message)
-        const workerId = this.getWorkerInfo(workerNodeKey).id
+        const workerId = this.getWorkerInfo(workerNodeKey)?.id
         if (
           message.taskFunctionOperationStatus != null &&
           message.workerId === workerId
@@ -1157,6 +1157,7 @@ export abstract class AbstractPool<
   private shallUpdateTaskFunctionWorkerUsage (workerNodeKey: number): boolean {
     const workerInfo = this.getWorkerInfo(workerNodeKey)
     return (
+      workerInfo != null &&
       Array.isArray(workerInfo.taskFunctionNames) &&
       workerInfo.taskFunctionNames.length > 2
     )
@@ -1536,13 +1537,14 @@ export abstract class AbstractPool<
       (this.info.stealingWorkerNodes ?? 0) >
         Math.floor(this.workerNodes.length / 2)
     ) {
-      if (previousStolenTask != null) {
+      if (workerInfo != null && previousStolenTask != null) {
         workerInfo.stealing = false
       }
       return
     }
     const workerNodeTasksUsage = this.workerNodes[workerNodeKey].usage.tasks
     if (
+      workerInfo != null &&
       previousStolenTask != null &&
       workerNodeTasksUsage.sequentiallyStolen > 0 &&
       (workerNodeTasksUsage.executing > 0 ||
@@ -1560,6 +1562,11 @@ export abstract class AbstractPool<
       this.resetTaskSequentiallyStolenStatisticsWorkerUsage(workerNodeKey)
       return
     }
+    if (workerInfo == null) {
+      throw new Error(
+        `Worker node with key '${workerNodeKey}' not found in pool`
+      )
+    }
     workerInfo.stealing = true
     const stolenTask = this.workerNodeStealTask(workerNodeKey)
     if (
@@ -1660,6 +1667,11 @@ export abstract class AbstractPool<
           this.opts.tasksQueueOptions!.size! - sizeOffset
       ) {
         const workerInfo = this.getWorkerInfo(workerNodeKey)
+        if (workerInfo == null) {
+          throw new Error(
+            `Worker node with key '${workerNodeKey}' not found in pool`
+          )
+        }
         workerInfo.stealing = true
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         const task = sourceWorkerNode.popTask()!
@@ -1687,9 +1699,12 @@ export abstract class AbstractPool<
       this.handleTaskExecutionResponse(message)
     } else if (taskFunctionNames != null) {
       // Task function names message received from worker
-      this.getWorkerInfo(
+      const workerInfo = this.getWorkerInfo(
         this.getWorkerNodeKeyByWorkerId(workerId)
-      ).taskFunctionNames = taskFunctionNames
+      )
+      if (workerInfo != null) {
+        workerInfo.taskFunctionNames = taskFunctionNames
+      }
     }
   }
 
@@ -1783,13 +1798,8 @@ export abstract class AbstractPool<
    * @param workerNodeKey - The worker node key.
    * @returns The worker information.
    */
-  protected getWorkerInfo (workerNodeKey: number): WorkerInfo {
-    const workerInfo = this.workerNodes[workerNodeKey]?.info
-    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
-    if (workerInfo == null) {
-      throw new Error(`Worker node with key '${workerNodeKey}' not found`)
-    }
-    return workerInfo
+  protected getWorkerInfo (workerNodeKey: number): WorkerInfo | undefined {
+    return this.workerNodes[workerNodeKey]?.info
   }
 
   /**
@@ -1848,7 +1858,10 @@ export abstract class AbstractPool<
   }
 
   protected flagWorkerNodeAsNotReady (workerNodeKey: number): void {
-    this.getWorkerInfo(workerNodeKey).ready = false
+    const workerInfo = this.getWorkerInfo(workerNodeKey)
+    if (workerInfo != null) {
+      workerInfo.ready = false
+    }
   }
 
   private hasBackPressure (): boolean {
index 09dbe509262a80148e2a46756fd86c992902be49..e4cc7d6e232d30d0da85607ec87661a31892c2c9 100644 (file)
@@ -54,7 +54,7 @@ export class FixedClusterPool<
   ): void {
     this.workerNodes[workerNodeKey].worker.send({
       ...message,
-      workerId: this.getWorkerInfo(workerNodeKey).id
+      workerId: this.getWorkerInfo(workerNodeKey)?.id
     })
   }
 
index ff427ea228533096c5fd93a3b92ce59963ca86a0..9561cc787a2cddbcb757fa1939cdeea25888a5a0 100644 (file)
@@ -54,7 +54,7 @@ export class FixedThreadPool<
     transferList?: TransferListItem[]
   ): void {
     this.workerNodes[workerNodeKey].messageChannel?.port1.postMessage(
-      { ...message, workerId: this.getWorkerInfo(workerNodeKey).id },
+      { ...message, workerId: this.getWorkerInfo(workerNodeKey)?.id },
       transferList
     )
   }
@@ -67,7 +67,7 @@ export class FixedThreadPool<
     workerNode.worker.postMessage(
       {
         ready: false,
-        workerId: this.getWorkerInfo(workerNodeKey).id,
+        workerId: this.getWorkerInfo(workerNodeKey)?.id,
         port: port2
       },
       [port2]