From a9d9ea34ae4621d0babc235b10614c7c8c37d88b Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sat, 1 Apr 2023 22:16:31 +0200 Subject: [PATCH] perf: only check worker status when necessary MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- README.md | 2 +- src/pools/abstract-pool.ts | 2 +- src/worker/abstract-worker.ts | 19 ++++++++++++------- src/worker/worker-options.ts | 4 ++-- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index bfb47a78..7087efa1 100644 --- 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` diff --git a/src/pools/abstract-pool.ts b/src/pools/abstract-pool.ts index 6531d661..122e9fa5 100644 --- a/src/pools/abstract-pool.ts +++ b/src/pools/abstract-pool.ts @@ -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 this.destroyWorker(workerCreated) } }) return workerCreated diff --git a/src/worker/abstract-worker.ts b/src/worker/abstract-worker.ts index 3a81e0f8..c71ff297 100644 --- a/src/worker/abstract-worker.ts +++ b/src/worker/abstract-worker.ts @@ -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) } diff --git a/src/worker/worker-options.ts b/src/worker/worker-options.ts index 290914f1..4e5a3d07 100644 --- a/src/worker/worker-options.ts +++ b/src/worker/worker-options.ts @@ -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. * -- 2.34.1