perf: only check worker status when necessary
authorJérôme Benoit <jerome.benoit@sap.com>
Sat, 1 Apr 2023 20:16:31 +0000 (22:16 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Sat, 1 Apr 2023 20:16:31 +0000 (22:16 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
README.md
src/pools/abstract-pool.ts
src/worker/abstract-worker.ts
src/worker/worker-options.ts

index bfb47a78d79d7f25aa9fbe2d1bf56c0da868e98a..7087efa1f0ded2513c154cc966790e0b2ad59031 100644 (file)
--- a/README.md
+++ b/README.md
@@ -203,7 +203,7 @@ This method will call the terminate method on each worker.
 - `async` - true/false, true if your function contains async code pieces, else false
 - `killBehavior` - Dictates if your async unit (worker/process) will be deleted in case that a task is active on it.  
   **KillBehaviors.SOFT**: If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker **won't** be deleted.  
-  **KillBehaviors.HARD**: If `lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.  
+  **KillBehaviors.HARD**: If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.  
   This option only apply to the newly created workers.  
   Default: `KillBehaviors.SOFT`
 
index 6531d6615349bda3b7223329977963ee7eba95a5..122e9fa5c9dbbad12f7eaf01b1db4f0b38ab35e4 100644 (file)
@@ -105,7 +105,7 @@ export abstract class AbstractPool<
             this.getWorkerRunningTasks(workerCreated) === 0
           ) {
             // Kill received from the worker, means that no new tasks are submitted to that worker for a while ( > maxInactiveTime)
-            void (this.destroyWorker(workerCreated) as Promise<void>)
+            void this.destroyWorker(workerCreated)
           }
         })
         return workerCreated
index 3a81e0f847f753ea55a7630d45a72fd08ec18a85..c71ff297e2485151a89f470c3c9eb4712122a83a 100644 (file)
@@ -3,7 +3,11 @@ import type { Worker } from 'cluster'
 import type { MessagePort } from 'worker_threads'
 import type { MessageValue } from '../utility-types'
 import { EMPTY_FUNCTION } from '../utils'
-import type { KillBehavior, WorkerOptions } from './worker-options'
+import {
+  isKillBehavior,
+  type KillBehavior,
+  type WorkerOptions
+} from './worker-options'
 import { KillBehaviors } from './worker-options'
 
 const DEFAULT_MAX_INACTIVE_TIME = 60000
@@ -24,7 +28,7 @@ export abstract class AbstractWorker<
   /**
    * Timestamp of the last task processed by this worker.
    */
-  protected lastTaskTimestamp: number
+  protected lastTaskTimestamp!: number
   /**
    * Handler Id of the `aliveInterval` worker alive check.
    */
@@ -63,9 +67,8 @@ export abstract class AbstractWorker<
     this.opts = opts
     this.checkFunctionInput(fn)
     this.checkWorkerOptions(this.opts)
-    this.lastTaskTimestamp = Date.now()
-    // Keep the worker active
-    if (!isMain) {
+    if (!isMain && isKillBehavior(KillBehaviors.HARD, this.opts.killBehavior)) {
+      this.lastTaskTimestamp = Date.now()
       this.aliveInterval = setInterval(
         this.checkAlive.bind(this),
         (this.opts.maxInactiveTime ?? DEFAULT_MAX_INACTIVE_TIME) / 2
@@ -179,7 +182,8 @@ export abstract class AbstractWorker<
       const err = this.handleError(e as Error)
       this.sendToMainWorker({ error: err, id: value.id })
     } finally {
-      this.lastTaskTimestamp = Date.now()
+      isKillBehavior(KillBehaviors.HARD, this.opts.killBehavior) &&
+        (this.lastTaskTimestamp = Date.now())
     }
   }
 
@@ -205,7 +209,8 @@ export abstract class AbstractWorker<
         this.sendToMainWorker({ error: err, id: value.id })
       })
       .finally(() => {
-        this.lastTaskTimestamp = Date.now()
+        isKillBehavior(KillBehaviors.HARD, this.opts.killBehavior) &&
+          (this.lastTaskTimestamp = Date.now())
       })
       .catch(EMPTY_FUNCTION)
   }
index 290914f1693d71b78f6af2445dbd4d1347b6e363..4e5a3d07d99c372b5d24854471d6b97f9c297566 100644 (file)
@@ -7,7 +7,7 @@ export const KillBehaviors = Object.freeze({
    */
   SOFT: 'SOFT',
   /**
-   * If `lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.
+   * If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.
    */
   HARD: 'HARD'
 } as const)
@@ -59,7 +59,7 @@ export interface WorkerOptions {
    * `killBehavior` dictates if your async unit (worker/process) will be deleted in case that a task is active on it.
    *
    * - SOFT: If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker **won't** be deleted.
-   * - HARD: If `lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.
+   * - HARD: If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.
    *
    * This option only apply to the newly created workers.
    *