build: make eslint configuration use strict type checking
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 3 Jan 2024 21:53:00 +0000 (22:53 +0100)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 3 Jan 2024 21:53:00 +0000 (22:53 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
29 files changed:
.eslintrc.cjs
examples/typescript/http-server-pool/express-cluster/src/main.ts
examples/typescript/http-server-pool/express-cluster/src/worker.ts
examples/typescript/http-server-pool/express-hybrid/src/express-worker.ts
examples/typescript/http-server-pool/express-hybrid/src/main.ts
examples/typescript/http-server-pool/fastify-cluster/src/main.ts
examples/typescript/http-server-pool/fastify-cluster/src/worker.ts
examples/typescript/http-server-pool/fastify-hybrid/src/fastify-worker.ts
examples/typescript/http-server-pool/fastify-hybrid/src/main.ts
examples/typescript/websocket-server-pool/ws-cluster/src/main.ts
examples/typescript/websocket-server-pool/ws-hybrid/src/main.ts
src/deque.ts
src/pools/abstract-pool.ts
src/pools/cluster/dynamic.ts
src/pools/cluster/fixed.ts
src/pools/selection-strategies/abstract-worker-choice-strategy.ts
src/pools/selection-strategies/interleaved-weighted-round-robin-worker-choice-strategy.ts
src/pools/selection-strategies/weighted-round-robin-worker-choice-strategy.ts
src/pools/thread/dynamic.ts
src/pools/thread/fixed.ts
src/pools/utils.ts
src/pools/worker-node.ts
src/pools/worker.ts
src/utils.ts
src/worker/abstract-worker.ts
src/worker/cluster-worker.ts
src/worker/thread-worker.ts
src/worker/utils.ts
tests/pools/utils.test.mjs

index 3ab81413bc179a47bc4f93094b9d6e73874daf7e..f8251b907d55a33c123a00329d307dde0f1204cd 100644 (file)
@@ -116,8 +116,8 @@ module.exports = defineConfig({
         project: './tsconfig.json'
       },
       extends: [
-        'plugin:@typescript-eslint/recommended',
-        'plugin:@typescript-eslint/recommended-requiring-type-checking',
+        'plugin:@typescript-eslint/strict-type-checked',
+        'plugin:@typescript-eslint/stylistic-type-checked',
         'plugin:import/typescript',
         'standard-with-typescript'
       ],
index 512f8d377f696f4c0534dbe381b110f827a6a72e..2184f970c3a819c2ed67ca02d1370c66e36a6b13 100644 (file)
@@ -19,8 +19,7 @@ const pool = new FixedClusterPool<WorkerData, WorkerResponse>(
         .then(response => {
           if (response.status) {
             console.info(
-              // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
-              `Express is listening in cluster worker on port ${response?.port}`
+              `Express is listening in cluster worker on port ${response.port}`
             )
           }
           return undefined
index 7b7087301c29fccbf85dcb74c3fda3a0b0e7e49d..d575647375edca90297ee647d0c4c26395e288f1 100644 (file)
@@ -35,13 +35,12 @@ class ExpressWorker extends ClusterWorker<WorkerData, WorkerResponse> {
 
     ExpressWorker.server = application.listen(port, () => {
       console.info(
-        // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
         `⚡️[express server]: Express server is started in cluster worker at http://localhost:${port}/`
       )
     })
     return {
       status: true,
-      port: (ExpressWorker.server.address() as AddressInfo)?.port ?? port
+      port: (ExpressWorker.server.address() as AddressInfo).port
     }
   }
 
index ac2e34d43bfc9ab2f97f51c4a874f2dee782495c..8cc041d4ee20c5f8e1fac45c96914019abcc2d9e 100644 (file)
@@ -70,13 +70,12 @@ ClusterWorkerResponse
 
     ExpressWorker.server = application.listen(port, () => {
       console.info(
-        // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
         `⚡️[express server]: Express server is started in cluster worker at http://localhost:${port}/`
       )
     })
     return {
       status: true,
-      port: (ExpressWorker.server.address() as AddressInfo)?.port ?? port
+      port: (ExpressWorker.server.address() as AddressInfo).port
     }
   }
 
index 040fdc74fea5d88b24474672128cc5988ffcc019..e339f83a276893e360140c77c40f510950e9406c 100644 (file)
@@ -38,8 +38,7 @@ const pool = new FixedClusterPool<ClusterWorkerData, ClusterWorkerResponse>(
         .then(response => {
           if (response.status) {
             console.info(
-              // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
-              `Express is listening in cluster worker on port ${response?.port}`
+              `Express is listening in cluster worker on port ${response.port}`
             )
           }
           return undefined
index 588adbedd44539fb8488ec22c616da1a955d7a44..6fe49edae8591ee64afb939053d37637f35b4ee2 100644 (file)
@@ -19,7 +19,6 @@ const pool = new FixedClusterPool<WorkerData, WorkerResponse>(
         .then(response => {
           if (response.status) {
             console.info(
-              // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
               `Fastify is listening in cluster worker on port ${response.port}`
             )
           }
index 1551cb282ede3679ade624acb473a8ac2ab568c3..5fca89058695c7a45614b15d2eeb10bd690d9491 100644 (file)
@@ -36,7 +36,7 @@ class FastifyWorker extends ClusterWorker<WorkerData, WorkerResponse> {
     await FastifyWorker.fastify.listen({ port })
     return {
       status: true,
-      port: (FastifyWorker.fastify.server.address() as AddressInfo)?.port
+      port: (FastifyWorker.fastify.server.address() as AddressInfo).port
     }
   }
 
index 28bf2a01f1cb0d15aff9b86d3bbbeed98c9bd808..0f4f6370b4c5249a2dfc8f2b4169d0245bbdda68 100644 (file)
@@ -42,7 +42,7 @@ ClusterWorkerResponse
     await FastifyWorker.fastify.listen({ port })
     return {
       status: true,
-      port: (FastifyWorker.fastify.server.address() as AddressInfo)?.port
+      port: (FastifyWorker.fastify.server.address() as AddressInfo).port
     }
   }
 
index d9a0015c637d528703902440ec0e986d5cc86450..6b9c172792805277e23800cb8bd6571f855670fa 100644 (file)
@@ -38,7 +38,6 @@ const pool = new FixedClusterPool<ClusterWorkerData, ClusterWorkerResponse>(
         .then(response => {
           if (response.status) {
             console.info(
-              // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
               `Fastify is listening in cluster worker on port ${response.port}`
             )
           }
index 695dc9545c99dcb308d35a5ceda62b5e87dc887b..762b1c0fffc68b24cfc4f7a4b8296649d1f151ec 100644 (file)
@@ -19,7 +19,6 @@ const pool = new FixedClusterPool<WorkerData, WorkerResponse>(
         .then(response => {
           if (response.status) {
             console.info(
-              // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
               `WebSocket server is listening in cluster worker on port ${response.port}`
             )
           }
index 177d7d3b5813f04ff10dd8812f8eafeec1099407..b35775b4b8e80b852ed31be2db04c955ae8f8996 100644 (file)
@@ -38,7 +38,6 @@ const pool = new FixedClusterPool<ClusterWorkerData, ClusterWorkerResponse>(
         .then(response => {
           if (response.status) {
             console.info(
-              // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
               `WebSocket server is listening in cluster worker on port ${response.port}`
             )
           }
index 00f60e6f7256c5204969ac827d4533cfaf177994..fe82a79896a08757e3f261b66aa364b1407ab6e9 100644 (file)
@@ -79,8 +79,7 @@ export class Deque<T> {
       return
     }
     const tail = this.tail
-    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    this.tail = this.tail!.prev
+    this.tail = this.tail?.prev
     if (this.tail == null) {
       delete this.head
     } else {
@@ -107,7 +106,7 @@ export class Deque<T> {
       delete this.head.prev
     }
     --this.size
-    return head?.data
+    return head.data
   }
 
   /**
@@ -156,8 +155,7 @@ export class Deque<T> {
           value: node.data,
           done: false
         }
-        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        node = node.next!
+        node = node.next
         return ret
       }
     }
@@ -185,8 +183,7 @@ export class Deque<T> {
               value: node.data,
               done: false
             }
-            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-            node = node.prev!
+            node = node.prev
             return ret
           }
         }
index 8e32218dfd521567663a27b09db1b2747d74b582..4170b8b61cd6f6e1f0de861ca6c94ee6278cb58f 100644 (file)
@@ -91,7 +91,7 @@ export abstract class AbstractPool<
   /**
    * Worker choice strategy context referencing a worker choice algorithm implementation.
    */
-  protected workerChoiceStrategyContext: WorkerChoiceStrategyContext<
+  protected workerChoiceStrategyContext?: WorkerChoiceStrategyContext<
   Worker,
   Data,
   Response
@@ -189,7 +189,9 @@ export abstract class AbstractPool<
     }
   }
 
-  private checkMinimumNumberOfWorkers (minimumNumberOfWorkers: number): void {
+  private checkMinimumNumberOfWorkers (
+    minimumNumberOfWorkers: number | undefined
+  ): void {
     if (minimumNumberOfWorkers == null) {
       throw new Error(
         'Cannot instantiate a pool without specifying the number of workers'
@@ -210,13 +212,11 @@ export abstract class AbstractPool<
   private checkPoolOptions (opts: PoolOptions<Worker>): void {
     if (isPlainObject(opts)) {
       this.opts.startWorkers = opts.startWorkers ?? true
-      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      checkValidWorkerChoiceStrategy(opts.workerChoiceStrategy!)
+      checkValidWorkerChoiceStrategy(opts.workerChoiceStrategy)
       this.opts.workerChoiceStrategy =
         opts.workerChoiceStrategy ?? WorkerChoiceStrategies.ROUND_ROBIN
       this.checkValidWorkerChoiceStrategyOptions(
-        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        opts.workerChoiceStrategyOptions!
+        opts.workerChoiceStrategyOptions
       )
       if (opts.workerChoiceStrategyOptions != null) {
         this.opts.workerChoiceStrategyOptions = opts.workerChoiceStrategyOptions
@@ -225,11 +225,9 @@ export abstract class AbstractPool<
       this.opts.enableEvents = opts.enableEvents ?? true
       this.opts.enableTasksQueue = opts.enableTasksQueue ?? false
       if (this.opts.enableTasksQueue) {
-        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        checkValidTasksQueueOptions(opts.tasksQueueOptions!)
+        checkValidTasksQueueOptions(opts.tasksQueueOptions)
         this.opts.tasksQueueOptions = this.buildTasksQueueOptions(
-          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-          opts.tasksQueueOptions!
+          opts.tasksQueueOptions
         )
       }
     } else {
@@ -238,7 +236,7 @@ export abstract class AbstractPool<
   }
 
   private checkValidWorkerChoiceStrategyOptions (
-    workerChoiceStrategyOptions: WorkerChoiceStrategyOptions
+    workerChoiceStrategyOptions: WorkerChoiceStrategyOptions | undefined
   ): void {
     if (
       workerChoiceStrategyOptions != null &&
@@ -288,9 +286,11 @@ export abstract class AbstractPool<
       minSize: this.minimumNumberOfWorkers,
       maxSize: this.maximumNumberOfWorkers ?? this.minimumNumberOfWorkers,
       ...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
-        .runTime.aggregate &&
-        this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
-          .waitTime.aggregate && { utilization: round(this.utilization) }),
+        ?.runTime.aggregate === true &&
+        this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
+          .waitTime.aggregate && {
+        utilization: round(this.utilization)
+      }),
       workerNodes: this.workerNodes.length,
       idleWorkerNodes: this.workerNodes.reduce(
         (accumulator, workerNode) =>
@@ -331,7 +331,7 @@ export abstract class AbstractPool<
       ...(this.opts.enableTasksQueue === true && {
         maxQueuedTasks: this.workerNodes.reduce(
           (accumulator, workerNode) =>
-            accumulator + (workerNode.usage.tasks?.maxQueued ?? 0),
+            accumulator + (workerNode.usage.tasks.maxQueued ?? 0),
           0
         )
       }),
@@ -351,23 +351,23 @@ export abstract class AbstractPool<
         0
       ),
       ...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
-        .runTime.aggregate && {
+        ?.runTime.aggregate === true && {
         runTime: {
           minimum: round(
             min(
               ...this.workerNodes.map(
-                workerNode => workerNode.usage.runTime?.minimum ?? Infinity
+                workerNode => workerNode.usage.runTime.minimum ?? Infinity
               )
             )
           ),
           maximum: round(
             max(
               ...this.workerNodes.map(
-                workerNode => workerNode.usage.runTime?.maximum ?? -Infinity
+                workerNode => workerNode.usage.runTime.maximum ?? -Infinity
               )
             )
           ),
-          ...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
+          ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
             .runTime.average && {
             average: round(
               average(
@@ -379,7 +379,7 @@ export abstract class AbstractPool<
               )
             )
           }),
-          ...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
+          ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
             .runTime.median && {
             median: round(
               median(
@@ -394,23 +394,23 @@ export abstract class AbstractPool<
         }
       }),
       ...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
-        .waitTime.aggregate && {
+        ?.waitTime.aggregate === true && {
         waitTime: {
           minimum: round(
             min(
               ...this.workerNodes.map(
-                workerNode => workerNode.usage.waitTime?.minimum ?? Infinity
+                workerNode => workerNode.usage.waitTime.minimum ?? Infinity
               )
             )
           ),
           maximum: round(
             max(
               ...this.workerNodes.map(
-                workerNode => workerNode.usage.waitTime?.maximum ?? -Infinity
+                workerNode => workerNode.usage.waitTime.maximum ?? -Infinity
               )
             )
           ),
-          ...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
+          ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
             .waitTime.average && {
             average: round(
               average(
@@ -422,7 +422,7 @@ export abstract class AbstractPool<
               )
             )
           }),
-          ...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
+          ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
             .waitTime.median && {
             median: round(
               median(
@@ -465,12 +465,12 @@ export abstract class AbstractPool<
       (this.maximumNumberOfWorkers ?? this.minimumNumberOfWorkers)
     const totalTasksRunTime = this.workerNodes.reduce(
       (accumulator, workerNode) =>
-        accumulator + (workerNode.usage.runTime?.aggregate ?? 0),
+        accumulator + (workerNode.usage.runTime.aggregate ?? 0),
       0
     )
     const totalTasksWaitTime = this.workerNodes.reduce(
       (accumulator, workerNode) =>
-        accumulator + (workerNode.usage.waitTime?.aggregate ?? 0),
+        accumulator + (workerNode.usage.waitTime.aggregate ?? 0),
       0
     )
     return (totalTasksRunTime + totalTasksWaitTime) / poolTimeCapacity
@@ -523,7 +523,7 @@ export abstract class AbstractPool<
   ): void {
     checkValidWorkerChoiceStrategy(workerChoiceStrategy)
     this.opts.workerChoiceStrategy = workerChoiceStrategy
-    this.workerChoiceStrategyContext.setWorkerChoiceStrategy(
+    this.workerChoiceStrategyContext?.setWorkerChoiceStrategy(
       this.opts.workerChoiceStrategy
     )
     if (workerChoiceStrategyOptions != null) {
@@ -537,13 +537,13 @@ export abstract class AbstractPool<
 
   /** @inheritDoc */
   public setWorkerChoiceStrategyOptions (
-    workerChoiceStrategyOptions: WorkerChoiceStrategyOptions
+    workerChoiceStrategyOptions: WorkerChoiceStrategyOptions | undefined
   ): void {
     this.checkValidWorkerChoiceStrategyOptions(workerChoiceStrategyOptions)
     if (workerChoiceStrategyOptions != null) {
       this.opts.workerChoiceStrategyOptions = workerChoiceStrategyOptions
     }
-    this.workerChoiceStrategyContext.setOptions(
+    this.workerChoiceStrategyContext?.setOptions(
       this.opts.workerChoiceStrategyOptions
     )
   }
@@ -559,12 +559,13 @@ export abstract class AbstractPool<
       this.flushTasksQueues()
     }
     this.opts.enableTasksQueue = enable
-    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    this.setTasksQueueOptions(tasksQueueOptions!)
+    this.setTasksQueueOptions(tasksQueueOptions)
   }
 
   /** @inheritDoc */
-  public setTasksQueueOptions (tasksQueueOptions: TasksQueueOptions): void {
+  public setTasksQueueOptions (
+    tasksQueueOptions: TasksQueueOptions | undefined
+  ): void {
     if (this.opts.enableTasksQueue === true) {
       checkValidTasksQueueOptions(tasksQueueOptions)
       this.opts.tasksQueueOptions =
@@ -589,7 +590,7 @@ export abstract class AbstractPool<
   }
 
   private buildTasksQueueOptions (
-    tasksQueueOptions: TasksQueueOptions
+    tasksQueueOptions: TasksQueueOptions | undefined
   ): TasksQueueOptions {
     return {
       ...getDefaultTasksQueueOptions(
@@ -702,24 +703,17 @@ export abstract class AbstractPool<
         message: MessageValue<Response>
       ): void => {
         this.checkMessageWorkerId(message)
-        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        const workerId = this.getWorkerInfo(workerNodeKey).id!
+        const workerId = this.getWorkerInfo(workerNodeKey).id
         if (
           message.taskFunctionOperationStatus != null &&
           message.workerId === workerId
         ) {
           if (message.taskFunctionOperationStatus) {
             resolve(true)
-          } else if (!message.taskFunctionOperationStatus) {
+          } else {
             reject(
               new Error(
-                `Task function operation '${
-                  message.taskFunctionOperation as string
-                  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-                }' failed on worker ${message.workerId} with error: '${
-                  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-                  message.workerError!.message
-                }'`
+                `Task function operation '${message.taskFunctionOperation}' failed on worker ${message.workerId} with error: '${message.workerError?.message}'`
               )
             )
           }
@@ -767,11 +761,8 @@ export abstract class AbstractPool<
                 new Error(
                   `Task function operation '${
                     message.taskFunctionOperation as string
-                    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-                  }' failed on worker ${errorResponse!
-                    .workerId!} with error: '${
-                    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-                    errorResponse!.workerError!.message
+                  }' failed on worker ${errorResponse?.workerId} with error: '${
+                    errorResponse?.workerError?.message
                   }'`
                 )
               )
@@ -998,7 +989,8 @@ export abstract class AbstractPool<
 
   private async sendKillMessageToWorker (workerNodeKey: number): Promise<void> {
     await new Promise<void>((resolve, reject) => {
-      if (this.workerNodes?.[workerNodeKey] == null) {
+      // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+      if (this.workerNodes[workerNodeKey] == null) {
         resolve()
         return
       }
@@ -1009,8 +1001,7 @@ export abstract class AbstractPool<
         } else if (message.kill === 'failure') {
           reject(
             new Error(
-              // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-              `Kill message handling failed on worker ${message.workerId!}`
+              `Kill message handling failed on worker ${message.workerId}`
             )
           )
         }
@@ -1069,7 +1060,8 @@ export abstract class AbstractPool<
     workerNodeKey: number,
     task: Task<Data>
   ): void {
-    if (this.workerNodes[workerNodeKey]?.usage != null) {
+    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+    if (this.workerNodes[workerNodeKey].usage != null) {
       const workerUsage = this.workerNodes[workerNodeKey].usage
       ++workerUsage.tasks.executing
       updateWaitTimeWorkerUsage(
@@ -1110,7 +1102,8 @@ export abstract class AbstractPool<
     message: MessageValue<Response>
   ): void {
     let needWorkerChoiceStrategyUpdate = false
-    if (this.workerNodes[workerNodeKey]?.usage != null) {
+    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+    if (this.workerNodes[workerNodeKey].usage != null) {
       const workerUsage = this.workerNodes[workerNodeKey].usage
       updateTaskStatisticsWorkerUsage(workerUsage, message)
       updateRunTimeWorkerUsage(
@@ -1151,7 +1144,7 @@ export abstract class AbstractPool<
       needWorkerChoiceStrategyUpdate = true
     }
     if (needWorkerChoiceStrategyUpdate) {
-      this.workerChoiceStrategyContext.update(workerNodeKey)
+      this.workerChoiceStrategyContext?.update(workerNodeKey)
     }
   }
 
@@ -1164,7 +1157,6 @@ 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
     )
@@ -1181,12 +1173,14 @@ export abstract class AbstractPool<
     if (this.shallCreateDynamicWorker()) {
       const workerNodeKey = this.createAndSetupDynamicWorkerNode()
       if (
-        this.workerChoiceStrategyContext.getStrategyPolicy().dynamicWorkerUsage
+        this.workerChoiceStrategyContext?.getStrategyPolicy()
+          .dynamicWorkerUsage === true
       ) {
         return workerNodeKey
       }
     }
-    return this.workerChoiceStrategyContext.execute()
+    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+    return this.workerChoiceStrategyContext!.execute()!
   }
 
   /**
@@ -1249,7 +1243,7 @@ export abstract class AbstractPool<
       ) {
         this.redistributeQueuedTasks(this.workerNodes.indexOf(workerNode))
       }
-      workerNode?.terminate().catch(error => {
+      workerNode.terminate().catch(error => {
         this.emitter?.emit(PoolEvents.error, error)
       })
     })
@@ -1312,8 +1306,10 @@ export abstract class AbstractPool<
     const workerNode = this.workerNodes[workerNodeKey]
     workerNode.info.dynamic = true
     if (
-      this.workerChoiceStrategyContext.getStrategyPolicy().dynamicWorkerReady ||
-      this.workerChoiceStrategyContext.getStrategyPolicy().dynamicWorkerUsage
+      this.workerChoiceStrategyContext?.getStrategyPolicy()
+        .dynamicWorkerReady === true ||
+      this.workerChoiceStrategyContext?.getStrategyPolicy()
+        .dynamicWorkerUsage === true
     ) {
       workerNode.info.ready = true
     }
@@ -1408,10 +1404,11 @@ export abstract class AbstractPool<
     this.sendToWorker(workerNodeKey, {
       statistics: {
         runTime:
-          this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
-            .runTime.aggregate,
-        elu: this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
-          .elu.aggregate
+          this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
+            ?.runTime.aggregate ?? false,
+        elu:
+          this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()?.elu
+            .aggregate ?? false
       }
     })
   }
@@ -1456,7 +1453,8 @@ export abstract class AbstractPool<
     taskName: string
   ): void {
     const workerNode = this.workerNodes[workerNodeKey]
-    if (workerNode?.usage != null) {
+    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+    if (workerNode.usage != null) {
       ++workerNode.usage.tasks.stolen
     }
     if (
@@ -1474,7 +1472,8 @@ export abstract class AbstractPool<
     workerNodeKey: number
   ): void {
     const workerNode = this.workerNodes[workerNodeKey]
-    if (workerNode?.usage != null) {
+    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+    if (workerNode.usage != null) {
       ++workerNode.usage.tasks.sequentiallyStolen
     }
   }
@@ -1499,7 +1498,8 @@ export abstract class AbstractPool<
     workerNodeKey: number
   ): void {
     const workerNode = this.workerNodes[workerNodeKey]
-    if (workerNode?.usage != null) {
+    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+    if (workerNode.usage != null) {
       workerNode.usage.tasks.sequentiallyStolen = 0
     }
   }
@@ -1527,16 +1527,17 @@ export abstract class AbstractPool<
     const { workerNodeKey } = eventDetail
     if (workerNodeKey == null) {
       throw new Error(
-        'WorkerNode event detail workerNodeKey property must be defined'
+        "WorkerNode event detail 'workerNodeKey' property must be defined"
       )
     }
+    const workerInfo = this.getWorkerInfo(workerNodeKey)
     if (
       this.cannotStealTask() ||
-      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      this.info.stealingWorkerNodes! > Math.floor(this.workerNodes.length / 2)
+      (this.info.stealingWorkerNodes ?? 0) >
+        Math.floor(this.workerNodes.length / 2)
     ) {
       if (previousStolenTask != null) {
-        this.getWorkerInfo(workerNodeKey).stealing = false
+        workerInfo.stealing = false
       }
       return
     }
@@ -1547,7 +1548,7 @@ export abstract class AbstractPool<
       (workerNodeTasksUsage.executing > 0 ||
         this.tasksQueueSize(workerNodeKey) > 0)
     ) {
-      this.getWorkerInfo(workerNodeKey).stealing = false
+      workerInfo.stealing = false
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       for (const taskName of this.workerNodes[workerNodeKey].info
         .taskFunctionNames!) {
@@ -1559,7 +1560,7 @@ export abstract class AbstractPool<
       this.resetTaskSequentiallyStolenStatisticsWorkerUsage(workerNodeKey)
       return
     }
-    this.getWorkerInfo(workerNodeKey).stealing = true
+    workerInfo.stealing = true
     const stolenTask = this.workerNodeStealTask(workerNodeKey)
     if (
       this.shallUpdateTaskFunctionWorkerUsage(workerNodeKey) &&
@@ -1629,8 +1630,8 @@ export abstract class AbstractPool<
   ): void => {
     if (
       this.cannotStealTask() ||
-      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      this.info.stealingWorkerNodes! > Math.floor(this.workerNodes.length / 2)
+      (this.info.stealingWorkerNodes ?? 0) >
+        Math.floor(this.workerNodes.length / 2)
     ) {
       return
     }
@@ -1658,13 +1659,14 @@ export abstract class AbstractPool<
           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
           this.opts.tasksQueueOptions!.size! - sizeOffset
       ) {
-        this.getWorkerInfo(workerNodeKey).stealing = true
+        const workerInfo = this.getWorkerInfo(workerNodeKey)
+        workerInfo.stealing = true
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         const task = sourceWorkerNode.popTask()!
         this.handleTask(workerNodeKey, task)
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         this.updateTaskStolenStatisticsWorkerUsage(workerNodeKey, task.name!)
-        this.getWorkerInfo(workerNodeKey).stealing = false
+        workerInfo.stealing = false
       }
     }
   }
@@ -1694,8 +1696,7 @@ export abstract class AbstractPool<
   private handleWorkerReadyResponse (message: MessageValue<Response>): void {
     const { workerId, ready, taskFunctionNames } = message
     if (ready == null || !ready) {
-      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      throw new Error(`Worker ${workerId!} failed to initialize`)
+      throw new Error(`Worker ${workerId} failed to initialize`)
     }
     const workerNode =
       this.workerNodes[this.getWorkerNodeKeyByWorkerId(workerId)]
@@ -1732,7 +1733,7 @@ export abstract class AbstractPool<
       this.afterTaskExecutionHook(workerNodeKey, message)
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       this.promiseResponseMap.delete(taskId!)
-      workerNode?.emit('taskFinished', taskId)
+      workerNode.emit('taskFinished', taskId)
       if (this.opts.enableTasksQueue === true && !this.destroying) {
         const workerNodeTasksUsage = workerNode.usage.tasks
         if (
@@ -1783,7 +1784,12 @@ export abstract class AbstractPool<
    * @returns The worker information.
    */
   protected getWorkerInfo (workerNodeKey: number): WorkerInfo {
-    return this.workerNodes[workerNodeKey]?.info
+    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
   }
 
   /**
@@ -1837,7 +1843,7 @@ export abstract class AbstractPool<
     const workerNodeKey = this.workerNodes.indexOf(workerNode)
     if (workerNodeKey !== -1) {
       this.workerNodes.splice(workerNodeKey, 1)
-      this.workerChoiceStrategyContext.remove(workerNodeKey)
+      this.workerChoiceStrategyContext?.remove(workerNodeKey)
     }
   }
 
index 564dbf54a91adec20804bc5598e800e8301e930a..7b2c37984ece0bff91021777653d90e6c3e5ccab 100644 (file)
@@ -34,8 +34,7 @@ export class DynamicClusterPool<
     super(min, filePath, opts, max)
     checkDynamicPoolSize(
       this.minimumNumberOfWorkers,
-      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      this.maximumNumberOfWorkers!
+      this.maximumNumberOfWorkers
     )
   }
 
index aa731562011507f59b84cce1f7088be68924e0b0..09dbe509262a80148e2a46756fd86c992902be49 100644 (file)
@@ -54,8 +54,7 @@ export class FixedClusterPool<
   ): void {
     this.workerNodes[workerNodeKey].worker.send({
       ...message,
-      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      workerId: this.getWorkerInfo(workerNodeKey).id!
+      workerId: this.getWorkerInfo(workerNodeKey).id
     })
   }
 
index 0a2b6113b8451bfabfd7fc866d59cc71b2f95ef2..55f43092d17760653168b59bee184fc508db1d54 100644 (file)
@@ -32,7 +32,7 @@ export abstract class AbstractWorkerChoiceStrategy<
   /**
    * The previous worker node key.
    */
-  protected previousWorkerNodeKey: number = 0
+  protected previousWorkerNodeKey = 0
 
   /** @inheritDoc */
   public readonly strategyPolicy: StrategyPolicy = {
index 3942bb6ed99961f986e1286ab20b31baf2a00eb5..e2aa0c6d03ceec1dabd8a012e92c7e72e4ca69ff 100644 (file)
@@ -36,7 +36,7 @@ export class InterleavedWeightedRoundRobinWorkerChoiceStrategy<
   /**
    * Round id.
    */
-  private roundId: number = 0
+  private roundId = 0
   /**
    * Round weights.
    */
@@ -44,11 +44,11 @@ export class InterleavedWeightedRoundRobinWorkerChoiceStrategy<
   /**
    * Worker node id.
    */
-  private workerNodeId: number = 0
+  private workerNodeId = 0
   /**
    * Worker node virtual task runtime.
    */
-  private workerNodeVirtualTaskRunTime: number = 0
+  private workerNodeVirtualTaskRunTime = 0
 
   /** @inheritDoc */
   public constructor (
index 6bbbbaf64738527cafb2720ae9a5ba73d7544c0e..94a832f626f90e03d71151be86d947a55c937b4d 100644 (file)
@@ -37,7 +37,7 @@ export class WeightedRoundRobinWorkerChoiceStrategy<
   /**
    * Worker node virtual task runtime.
    */
-  private workerNodeVirtualTaskRunTime: number = 0
+  private workerNodeVirtualTaskRunTime = 0
 
   /** @inheritDoc */
   public constructor (
index 836cae0b0615e1f74733e09f9f21b450bf15506b..fde371048c5755c77736c6a25545fe19aa90df8d 100644 (file)
@@ -34,8 +34,7 @@ export class DynamicThreadPool<
     super(min, filePath, opts, max)
     checkDynamicPoolSize(
       this.minimumNumberOfWorkers,
-      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      this.maximumNumberOfWorkers!
+      this.maximumNumberOfWorkers
     )
   }
 
index c4256bf3b2213d8d7a6a60d7df8a95447576b888..ff427ea228533096c5fd93a3b92ce59963ca86a0 100644 (file)
@@ -53,7 +53,7 @@ export class FixedThreadPool<
     message: MessageValue<Data>,
     transferList?: TransferListItem[]
   ): void {
-    this.workerNodes[workerNodeKey].messageChannel?.port1?.postMessage(
+    this.workerNodes[workerNodeKey].messageChannel?.port1.postMessage(
       { ...message, workerId: this.getWorkerInfo(workerNodeKey).id },
       transferList
     )
@@ -79,7 +79,7 @@ export class FixedThreadPool<
     workerNodeKey: number,
     listener: (message: MessageValue<Message>) => void
   ): void {
-    this.workerNodes[workerNodeKey].messageChannel?.port1?.on(
+    this.workerNodes[workerNodeKey].messageChannel?.port1.on(
       'message',
       listener
     )
@@ -90,7 +90,7 @@ export class FixedThreadPool<
     workerNodeKey: number,
     listener: (message: MessageValue<Message>) => void
   ): void {
-    this.workerNodes[workerNodeKey].messageChannel?.port1?.once(
+    this.workerNodes[workerNodeKey].messageChannel?.port1.once(
       'message',
       listener
     )
@@ -101,7 +101,7 @@ export class FixedThreadPool<
     workerNodeKey: number,
     listener: (message: MessageValue<Message>) => void
   ): void {
-    this.workerNodes[workerNodeKey].messageChannel?.port1?.off(
+    this.workerNodes[workerNodeKey].messageChannel?.port1.off(
       'message',
       listener
     )
index 99584d8528d65f5538d3f89e309a6dd77d4fde79..c0e803a2f4cb5a2bd88b3350e98b3a754c4e5b51 100644 (file)
@@ -33,7 +33,7 @@ export const getDefaultTasksQueueOptions = (
   }
 }
 
-export const checkFilePath = (filePath: string): void => {
+export const checkFilePath = (filePath: string | undefined): void => {
   if (filePath == null) {
     throw new TypeError('The worker file path must be specified')
   }
@@ -45,7 +45,10 @@ export const checkFilePath = (filePath: string): void => {
   }
 }
 
-export const checkDynamicPoolSize = (min: number, max: number): void => {
+export const checkDynamicPoolSize = (
+  min: number,
+  max: number | undefined
+): void => {
   if (max == null) {
     throw new TypeError(
       'Cannot instantiate a dynamic pool without specifying the maximum pool size'
@@ -70,7 +73,7 @@ export const checkDynamicPoolSize = (min: number, max: number): void => {
 }
 
 export const checkValidWorkerChoiceStrategy = (
-  workerChoiceStrategy: WorkerChoiceStrategy
+  workerChoiceStrategy: WorkerChoiceStrategy | undefined
 ): void => {
   if (
     workerChoiceStrategy != null &&
@@ -81,7 +84,7 @@ export const checkValidWorkerChoiceStrategy = (
 }
 
 export const checkValidTasksQueueOptions = (
-  tasksQueueOptions: TasksQueueOptions
+  tasksQueueOptions: TasksQueueOptions | undefined
 ): void => {
   if (tasksQueueOptions != null && !isPlainObject(tasksQueueOptions)) {
     throw new TypeError('Invalid tasks queue options: must be a plain object')
@@ -118,9 +121,9 @@ export const checkValidTasksQueueOptions = (
 }
 
 export const checkWorkerNodeArguments = (
-  type: WorkerType,
-  filePath: string,
-  opts: WorkerNodeOptions
+  type: WorkerType | undefined,
+  filePath: string | undefined,
+  opts: WorkerNodeOptions | undefined
 ): void => {
   if (type == null) {
     throw new TypeError('Cannot construct a worker node without a worker type')
@@ -168,10 +171,14 @@ export const checkWorkerNodeArguments = (
  */
 const updateMeasurementStatistics = (
   measurementStatistics: MeasurementStatistics,
-  measurementRequirements: MeasurementStatisticsRequirements,
-  measurementValue: number
+  measurementRequirements: MeasurementStatisticsRequirements | undefined,
+  measurementValue: number | undefined
 ): void => {
-  if (measurementRequirements.aggregate) {
+  if (
+    measurementRequirements != null &&
+    measurementValue != null &&
+    measurementRequirements.aggregate
+  ) {
     measurementStatistics.aggregate =
       (measurementStatistics.aggregate ?? 0) + measurementValue
     measurementStatistics.minimum = min(
@@ -182,10 +189,7 @@ const updateMeasurementStatistics = (
       measurementValue,
       measurementStatistics.maximum ?? -Infinity
     )
-    if (
-      (measurementRequirements.average || measurementRequirements.median) &&
-      measurementValue != null
-    ) {
+    if (measurementRequirements.average || measurementRequirements.median) {
       measurementStatistics.history.push(measurementValue)
       if (measurementRequirements.average) {
         measurementStatistics.average = average(measurementStatistics.history)
@@ -210,11 +214,9 @@ export const updateWaitTimeWorkerUsage = <
   Data = unknown,
   Response = unknown
 >(
-    workerChoiceStrategyContext: WorkerChoiceStrategyContext<
-    Worker,
-    Data,
-    Response
-    >,
+    workerChoiceStrategyContext:
+    | WorkerChoiceStrategyContext<Worker, Data, Response>
+    | undefined,
     workerUsage: WorkerUsage,
     task: Task<Data>
   ): void => {
@@ -222,7 +224,7 @@ export const updateWaitTimeWorkerUsage = <
   const taskWaitTime = timestamp - (task.timestamp ?? timestamp)
   updateMeasurementStatistics(
     workerUsage.waitTime,
-    workerChoiceStrategyContext.getTaskStatisticsRequirements().waitTime,
+    workerChoiceStrategyContext?.getTaskStatisticsRequirements()?.waitTime,
     taskWaitTime
   )
 }
@@ -233,6 +235,7 @@ export const updateTaskStatisticsWorkerUsage = <Response = unknown>(
 ): void => {
   const workerTaskStatistics = workerUsage.tasks
   if (
+    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
     workerTaskStatistics.executing != null &&
     workerTaskStatistics.executing > 0
   ) {
@@ -250,11 +253,9 @@ export const updateRunTimeWorkerUsage = <
   Data = unknown,
   Response = unknown
 >(
-    workerChoiceStrategyContext: WorkerChoiceStrategyContext<
-    Worker,
-    Data,
-    Response
-    >,
+    workerChoiceStrategyContext:
+    | WorkerChoiceStrategyContext<Worker, Data, Response>
+    | undefined,
     workerUsage: WorkerUsage,
     message: MessageValue<Response>
   ): void => {
@@ -263,7 +264,7 @@ export const updateRunTimeWorkerUsage = <
   }
   updateMeasurementStatistics(
     workerUsage.runTime,
-    workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime,
+    workerChoiceStrategyContext?.getTaskStatisticsRequirements()?.runTime,
     message.taskPerformance?.runTime ?? 0
   )
 }
@@ -273,19 +274,17 @@ export const updateEluWorkerUsage = <
   Data = unknown,
   Response = unknown
 >(
-    workerChoiceStrategyContext: WorkerChoiceStrategyContext<
-    Worker,
-    Data,
-    Response
-    >,
+    workerChoiceStrategyContext:
+    | WorkerChoiceStrategyContext<Worker, Data, Response>
+    | undefined,
     workerUsage: WorkerUsage,
     message: MessageValue<Response>
   ): void => {
   if (message.workerError != null) {
     return
   }
-  const eluTaskStatisticsRequirements: MeasurementStatisticsRequirements =
-    workerChoiceStrategyContext.getTaskStatisticsRequirements().elu
+  const eluTaskStatisticsRequirements =
+    workerChoiceStrategyContext?.getTaskStatisticsRequirements()?.elu
   updateMeasurementStatistics(
     workerUsage.elu.active,
     eluTaskStatisticsRequirements,
@@ -296,7 +295,7 @@ export const updateEluWorkerUsage = <
     eluTaskStatisticsRequirements,
     message.taskPerformance?.elu?.idle ?? 0
   )
-  if (eluTaskStatisticsRequirements.aggregate) {
+  if (eluTaskStatisticsRequirements?.aggregate === true) {
     if (message.taskPerformance?.elu != null) {
       if (workerUsage.elu.utilization != null) {
         workerUsage.elu.utilization =
@@ -319,10 +318,10 @@ export const createWorker = <Worker extends IWorker>(
     case WorkerTypes.thread:
       return new Worker(filePath, {
         env: SHARE_ENV,
-        ...opts?.workerOptions
+        ...opts.workerOptions
       }) as unknown as Worker
     case WorkerTypes.cluster:
-      return cluster.fork(opts?.env) as unknown as Worker
+      return cluster.fork(opts.env) as unknown as Worker
     default:
       // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
       throw new Error(`Unknown worker type '${type}'`)
index 73b2c70c3f3b05ce1031bf57fe5522c40874cfa6..9fa4ea3201e3ca0db3d3aa9f79153adc3f1625d5 100644 (file)
@@ -61,7 +61,8 @@ export class WorkerNode<Worker extends IWorker, Data = unknown>
     if (this.info.type === WorkerTypes.thread) {
       this.messageChannel = new MessageChannel()
     }
-    this.tasksQueueBackPressureSize = opts.tasksQueueBackPressureSize
+    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+    this.tasksQueueBackPressureSize = opts.tasksQueueBackPressureSize!
     this.tasksQueue = new Deque<Task<Data>>()
     this.onBackPressureStarted = false
     this.taskFunctionsUsage = new Map<string, WorkerUsage>()
index f439c882a66a703e23cffafc6d02b5f0fcb7fef1..7f8148ffcc93db670479a9ce5d7c96b6e576a1d0 100644 (file)
@@ -258,7 +258,7 @@ export interface IWorker {
 export interface WorkerNodeOptions {
   workerOptions?: WorkerOptions
   env?: Record<string, unknown>
-  tasksQueueBackPressureSize: number
+  tasksQueueBackPressureSize: number | undefined
 }
 
 /**
index a7cb55f971483d12729e259110b3d872da7b5f15..b38cf948e833ef41ccc7d183db0498a8e4257ed0 100644 (file)
@@ -178,7 +178,7 @@ export const round = (num: number, scale = 2): number => {
 export const isPlainObject = (obj: unknown): boolean =>
   typeof obj === 'object' &&
   obj !== null &&
-  obj?.constructor === Object &&
+  obj.constructor === Object &&
   Object.prototype.toString.call(obj) === '[object Object]'
 
 /**
@@ -257,6 +257,7 @@ export const once = <T, A extends any[], R>(
 ): ((...args: A) => R) => {
   let result: R
   return (...args: A) => {
+    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
     if (fn != null) {
       result = fn.apply<T, A, R>(context, args)
       ;(fn as unknown as undefined) = (context as unknown as undefined) =
@@ -293,7 +294,7 @@ export const buildWorkerChoiceStrategyOptions = <
     opts?: WorkerChoiceStrategyOptions
   ): WorkerChoiceStrategyOptions => {
   opts = clone(opts ?? {})
-  opts.weights = opts?.weights ?? getDefaultWeights(pool.info.maxSize)
+  opts.weights = opts.weights ?? getDefaultWeights(pool.info.maxSize)
   return {
     ...{
       runTime: { median: false },
@@ -320,8 +321,10 @@ const getDefaultWorkerWeight = (): number => {
   const cpuSpeed = randomInt(500, 2500)
   let cpusCycleTimeWeight = 0
   for (const cpu of cpus()) {
+    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
     if (cpu.speed == null || cpu.speed === 0) {
       cpu.speed =
+        // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
         cpus().find(cpu => cpu.speed != null && cpu.speed !== 0)?.speed ??
         cpuSpeed
     }
index 2359758dc72c2a362b60e513890664731fdc7fea..890f340e69a63ac1bce217ecafa0ae5191febae1 100644 (file)
@@ -71,7 +71,7 @@ export abstract class AbstractWorker<
   /**
    * Performance statistics computation requirements.
    */
-  protected statistics!: WorkerStatistics
+  protected statistics?: WorkerStatistics
   /**
    * Handler id of the `activeInterval` worker activity check.
    */
@@ -86,8 +86,8 @@ export abstract class AbstractWorker<
    * @param opts - Options for the worker.
    */
   public constructor (
-    protected readonly isMain: boolean,
-    private readonly mainWorker: MainWorker,
+    protected readonly isMain: boolean | undefined,
+    private readonly mainWorker: MainWorker | undefined | null,
     taskFunctions: TaskFunction<Data, Response> | TaskFunctions<Data, Response>,
     protected opts: WorkerOptions = DEFAULT_WORKER_OPTIONS
   ) {
@@ -113,7 +113,10 @@ export abstract class AbstractWorker<
    * @param taskFunctions - The task function(s) parameter that should be checked.
    */
   private checkTaskFunctions (
-    taskFunctions: TaskFunction<Data, Response> | TaskFunctions<Data, Response>
+    taskFunctions:
+    | TaskFunction<Data, Response>
+    | TaskFunctions<Data, Response>
+    | undefined
   ): void {
     if (taskFunctions == null) {
       throw new Error('taskFunctions parameter is mandatory')
@@ -352,7 +355,7 @@ export abstract class AbstractWorker<
       taskFunctionOperationStatus: response.status,
       taskFunctionName,
       ...(!response.status &&
-        response?.error != null && {
+        response.error != null && {
         workerError: {
           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
           name: taskFunctionName!,
@@ -370,7 +373,7 @@ export abstract class AbstractWorker<
   protected handleKillMessage (_message: MessageValue<Data>): void {
     this.stopCheckActive()
     if (isAsyncFunction(this.opts.killHandler)) {
-      (this.opts.killHandler?.() as Promise<void>)
+      (this.opts.killHandler() as Promise<void>)
         .then(() => {
           this.sendToMainWorker({ kill: 'success' })
           return undefined
@@ -492,8 +495,7 @@ export abstract class AbstractWorker<
         workerError: {
           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
           name: name!,
-          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-          message: `Task function '${name!}' not found`,
+          message: `Task function '${name}' not found`,
           data
         },
         taskId
@@ -583,18 +585,24 @@ export abstract class AbstractWorker<
   }
 
   private beginTaskPerformance (name?: string): TaskPerformance {
-    this.checkStatistics()
+    if (this.statistics == null) {
+      throw new Error('Performance statistics computation requirements not set')
+    }
     return {
       name: name ?? DEFAULT_TASK_NAME,
       timestamp: performance.now(),
-      ...(this.statistics.elu && { elu: performance.eventLoopUtilization() })
+      ...(this.statistics.elu && {
+        elu: performance.eventLoopUtilization()
+      })
     }
   }
 
   private endTaskPerformance (
     taskPerformance: TaskPerformance
   ): TaskPerformance {
-    this.checkStatistics()
+    if (this.statistics == null) {
+      throw new Error('Performance statistics computation requirements not set')
+    }
     return {
       ...taskPerformance,
       ...(this.statistics.runTime && {
@@ -606,12 +614,6 @@ export abstract class AbstractWorker<
     }
   }
 
-  private checkStatistics (): void {
-    if (this.statistics == null) {
-      throw new Error('Performance statistics computation requirements not set')
-    }
-  }
-
   private updateLastTaskTimestamp (): void {
     if (this.activeInterval != null) {
       this.lastTaskTimestamp = performance.now()
index 05fe25343acc736f53085947e551e3869486bf5f..1a9deb304aaebf8f919cf91716427e865d58a02d 100644 (file)
@@ -32,8 +32,7 @@ export class ClusterWorker<
     taskFunctions: TaskFunction<Data, Response> | TaskFunctions<Data, Response>,
     opts: WorkerOptions = {}
   ) {
-    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    super(cluster.isPrimary, cluster.worker!, taskFunctions, opts)
+    super(cluster.isPrimary, cluster.worker, taskFunctions, opts)
   }
 
   /** @inheritDoc */
index 7f3cd950a992269fb7917b7eda296419a501b6f8..3635d92c56006b0d0f6dbcf6f855fdfaf52865bf 100644 (file)
@@ -42,8 +42,7 @@ export class ThreadWorker<
     taskFunctions: TaskFunction<Data, Response> | TaskFunctions<Data, Response>,
     opts: WorkerOptions = {}
   ) {
-    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    super(isMainThread, parentPort!, taskFunctions, opts)
+    super(isMainThread, parentPort, taskFunctions, opts)
   }
 
   /** @inheritDoc */
index b9372401ed881988d893248167d98a6b222c00be..d8c4c3e905318b3c485991155c65cfdc03f269a7 100644 (file)
@@ -2,7 +2,9 @@ import { isPlainObject } from '../utils.js'
 import type { TaskFunction } from './task-functions.js'
 import { KillBehaviors, type WorkerOptions } from './worker-options.js'
 
-export const checkValidWorkerOptions = (opts: WorkerOptions): void => {
+export const checkValidWorkerOptions = (
+  opts: WorkerOptions | undefined
+): void => {
   if (opts != null && !isPlainObject(opts)) {
     throw new TypeError('opts worker options parameter is not a plain object')
   }
index bc0c7126ddaa225c92e5e8c2f13174e2e2eaa760..610b92c3ce62cba912ab9273b14d5cb2077f9884 100644 (file)
@@ -115,13 +115,15 @@ describe('Pool utils test suite', () => {
     expect(
       createWorker(
         WorkerTypes.thread,
-        './tests/worker-files/thread/testWorker.mjs'
+        './tests/worker-files/thread/testWorker.mjs',
+        {}
       )
     ).toBeInstanceOf(ThreadWorker)
     expect(
       createWorker(
         WorkerTypes.cluster,
-        './tests/worker-files/cluster/testWorker.mjs'
+        './tests/worker-files/cluster/testWorker.mjs',
+        {}
       )
     ).toBeInstanceOf(ClusterWorker)
   })