From 3fafb1b2f068533b39818d66b5b0b9972f76f577 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sat, 8 Apr 2023 15:03:31 +0200 Subject: [PATCH] feat: use monotonic high resolution timer for worker tasks statistics MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- .eslintrc.js | 1 + CHANGELOG.md | 5 ++++ .../fair-share-worker-choice-strategy.ts | 2 +- src/worker/abstract-worker.ts | 28 ++++++++++++------- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 4fc34807..71acb042 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -46,6 +46,7 @@ module.exports = defineConfig({ 'esm', 'fibonacci', 'fs', + 'hrtime', 'inheritDoc', 'jsdoc', 'microjob', diff --git a/CHANGELOG.md b/CHANGELOG.md index 52b7626f..b2e14ab3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Use monotonic high resolution timer for worker tasks run time. +- Add worker tasks median run time to statistics. + ## [2.4.4] - 2023-04-07 ### Added diff --git a/src/pools/selection-strategies/fair-share-worker-choice-strategy.ts b/src/pools/selection-strategies/fair-share-worker-choice-strategy.ts index fc4f0f69..e16c1ea2 100644 --- a/src/pools/selection-strategies/fair-share-worker-choice-strategy.ts +++ b/src/pools/selection-strategies/fair-share-worker-choice-strategy.ts @@ -85,7 +85,7 @@ export class FairShareWorkerChoiceStrategy< */ private computeWorkerLastVirtualTaskTimestamp (workerKey: number): void { const workerVirtualTaskStartTimestamp = Math.max( - Date.now(), + performance.now(), this.workerLastVirtualTaskTimestamp.get(workerKey)?.end ?? -Infinity ) this.workerLastVirtualTaskTimestamp.set(workerKey, { diff --git a/src/worker/abstract-worker.ts b/src/worker/abstract-worker.ts index 10a0c82d..b588b181 100644 --- a/src/worker/abstract-worker.ts +++ b/src/worker/abstract-worker.ts @@ -59,7 +59,7 @@ export abstract class AbstractWorker< this.checkFunctionInput(fn) this.checkWorkerOptions(this.opts) if (!this.isMain) { - this.lastTaskTimestamp = Date.now() + this.lastTaskTimestamp = performance.now() this.aliveInterval = setInterval( this.checkAlive.bind(this), (this.opts.maxInactiveTime ?? DEFAULT_MAX_INACTIVE_TIME) / 2 @@ -145,7 +145,7 @@ export abstract class AbstractWorker< */ protected checkAlive (): void { if ( - Date.now() - this.lastTaskTimestamp > + performance.now() - this.lastTaskTimestamp > (this.opts.maxInactiveTime ?? DEFAULT_MAX_INACTIVE_TIME) ) { this.sendToMainWorker({ kill: this.opts.killBehavior }) @@ -173,15 +173,19 @@ export abstract class AbstractWorker< message: MessageValue ): void { try { - const startTimestamp = Date.now() + const startTimestamp = performance.now() const res = fn(message.data) - const runTime = Date.now() - startTimestamp - this.sendToMainWorker({ data: res, id: message.id, runTime }) + const runTime = performance.now() - startTimestamp + this.sendToMainWorker({ + data: res, + id: message.id, + runTime + }) } catch (e) { const err = this.handleError(e as Error) this.sendToMainWorker({ error: err, id: message.id }) } finally { - !this.isMain && (this.lastTaskTimestamp = Date.now()) + !this.isMain && (this.lastTaskTimestamp = performance.now()) } } @@ -195,11 +199,15 @@ export abstract class AbstractWorker< fn: (data?: Data) => Promise, message: MessageValue ): void { - const startTimestamp = Date.now() + const startTimestamp = performance.now() fn(message.data) .then(res => { - const runTime = Date.now() - startTimestamp - this.sendToMainWorker({ data: res, id: message.id, runTime }) + const runTime = performance.now() - startTimestamp + this.sendToMainWorker({ + data: res, + id: message.id, + runTime + }) return null }) .catch(e => { @@ -207,7 +215,7 @@ export abstract class AbstractWorker< this.sendToMainWorker({ error: err, id: message.id }) }) .finally(() => { - !this.isMain && (this.lastTaskTimestamp = Date.now()) + !this.isMain && (this.lastTaskTimestamp = performance.now()) }) .catch(EMPTY_FUNCTION) } -- 2.34.1