From c20084b62c59a6a34f4924601fa8ae5bf0a1943f Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sun, 17 Sep 2023 17:51:03 +0200 Subject: [PATCH] refactor: stricter worker constructor arguments check MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- CHANGELOG.md | 4 +++ docs/api.md | 2 +- src/worker/abstract-worker.ts | 31 +++++++++++++++++-- tests/worker/abstract-worker.test.js | 46 ++++++++++++++++++++++++++-- 4 files changed, 77 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6b20e1a..ad5bfde0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix task stealing related tasks queue options handling at runtime. +### Changed + +- Stricter worker constructor arguments validation. + ## [2.6.45] - 2023-09-17 ### Changed diff --git a/docs/api.md b/docs/api.md index 7939123b..c8a135f1 100644 --- a/docs/api.md +++ b/docs/api.md @@ -135,7 +135,7 @@ An object with these properties: This option only apply to the newly created workers. Default: `KillBehaviors.SOFT` -- `maxInactiveTime` (optional) - Maximum waiting time in milliseconds for tasks on newly created workers. After this time newly created workers will die. +- `maxInactiveTime` (optional) - Maximum waiting time in milliseconds for tasks on newly created workers. After this time newly created workers will die. It must be a positive integer greater or equal than 5. The last active time of your worker will be updated when it terminates a task. If `killBehavior` is set to `KillBehaviors.HARD` this value represents also the timeout for the tasks that you submit to the pool, when this timeout expires your tasks is interrupted before completion and removed. The worker is killed if is not part of the minimum size of the pool. If `killBehavior` is set to `KillBehaviors.SOFT` your tasks have no timeout and your workers will not be terminated until your task is completed. diff --git a/src/worker/abstract-worker.ts b/src/worker/abstract-worker.ts index cd8f2346..8551ffc8 100644 --- a/src/worker/abstract-worker.ts +++ b/src/worker/abstract-worker.ts @@ -99,8 +99,35 @@ export abstract class AbstractWorker< } private checkWorkerOptions (opts: WorkerOptions): void { + if (opts != null && !isPlainObject(opts)) { + throw new TypeError('opts worker options parameter is not a plain object') + } + if ( + opts?.killBehavior != null && + !Object.values(KillBehaviors).includes(opts.killBehavior) + ) { + throw new TypeError( + `killBehavior option '${opts.killBehavior}' is not valid` + ) + } + if ( + opts?.maxInactiveTime != null && + !Number.isSafeInteger(opts.maxInactiveTime) + ) { + throw new TypeError('maxInactiveTime option is not an integer') + } + if (opts?.maxInactiveTime != null && opts.maxInactiveTime < 5) { + throw new TypeError( + 'maxInactiveTime option is not a positive integer greater or equal than 5' + ) + } + if (opts?.killHandler != null && typeof opts.killHandler !== 'function') { + throw new TypeError('killHandler option is not a function') + } + if (opts?.async != null) { + throw new Error('async option is deprecated') + } this.opts = { ...DEFAULT_WORKER_OPTIONS, ...opts } - delete this.opts.async } private checkValidTaskFunction ( @@ -125,7 +152,7 @@ export abstract class AbstractWorker< } /** - * Checks if the `taskFunctions` parameter is passed to the constructor. + * Checks if the `taskFunctions` parameter is passed to the constructor and valid. * * @param taskFunctions - The task function(s) parameter that should be checked. */ diff --git a/tests/worker/abstract-worker.test.js b/tests/worker/abstract-worker.test.js index 62f6dd2b..5860ebff 100644 --- a/tests/worker/abstract-worker.test.js +++ b/tests/worker/abstract-worker.test.js @@ -24,6 +24,47 @@ describe('Abstract worker test suite', () => { }) }) + it('Verify that worker options are checked at worker creation', () => { + expect(() => new ClusterWorker(() => {}, '')).toThrowError( + new TypeError('opts worker options parameter is not a plain object') + ) + expect( + () => new ClusterWorker(() => {}, { killBehavior: '' }) + ).toThrowError(new TypeError("killBehavior option '' is not valid")) + expect(() => new ClusterWorker(() => {}, { killBehavior: 0 })).toThrowError( + new TypeError("killBehavior option '0' is not valid") + ) + expect( + () => new ThreadWorker(() => {}, { maxInactiveTime: '' }) + ).toThrowError(new TypeError('maxInactiveTime option is not an integer')) + expect( + () => new ThreadWorker(() => {}, { maxInactiveTime: 0.5 }) + ).toThrowError(new TypeError('maxInactiveTime option is not an integer')) + expect( + () => new ThreadWorker(() => {}, { maxInactiveTime: 0 }) + ).toThrowError( + new TypeError( + 'maxInactiveTime option is not a positive integer greater or equal than 5' + ) + ) + expect( + () => new ThreadWorker(() => {}, { maxInactiveTime: 4 }) + ).toThrowError( + new TypeError( + 'maxInactiveTime option is not a positive integer greater or equal than 5' + ) + ) + expect(() => new ThreadWorker(() => {}, { killHandler: '' })).toThrowError( + new TypeError('killHandler option is not a function') + ) + expect(() => new ThreadWorker(() => {}, { killHandler: 0 })).toThrowError( + new TypeError('killHandler option is not a function') + ) + expect(() => new ThreadWorker(() => {}, { async: true })).toThrowError( + new TypeError('async option is deprecated') + ) + }) + it('Verify that worker options are set at worker creation', () => { const killHandler = () => { console.info('Worker received kill message') @@ -31,8 +72,7 @@ describe('Abstract worker test suite', () => { const worker = new ClusterWorker(() => {}, { killBehavior: KillBehaviors.HARD, maxInactiveTime: 6000, - killHandler, - async: true + killHandler }) expect(worker.opts).toStrictEqual({ killBehavior: KillBehaviors.HARD, @@ -43,7 +83,7 @@ describe('Abstract worker test suite', () => { it('Verify that taskFunctions parameter is mandatory', () => { expect(() => new ClusterWorker()).toThrowError( - 'taskFunctions parameter is mandatory' + new Error('taskFunctions parameter is mandatory') ) }) -- 2.34.1