refactor: stricter worker constructor arguments check
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Sun, 17 Sep 2023 15:51:03 +0000 (17:51 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Sun, 17 Sep 2023 15:51:03 +0000 (17:51 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
CHANGELOG.md
docs/api.md
src/worker/abstract-worker.ts
tests/worker/abstract-worker.test.js

index a6b20e1a0b0ea610fa50af70e616a8a5de12792a..ad5bfde0f264bd84b5719d8dba1b635e1ff033f0 100644 (file)
@@ -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
index 7939123b1e64b0bcbe5c75103aeb3f93a47ba830..c8a135f150d75b441216546b1cb0fa3c0e7bd95c 100644 (file)
@@ -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.  
index cd8f2346365f20ca5fb9e029dd436113594f19ac..8551ffc8ae2eef49bfb61567198ead269fef6bd7 100644 (file)
@@ -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.
    */
index 62f6dd2bea37b3e8f4789ea2ed7c027cc0fe7a43..5860ebffa07aaa41f7edc7ff4c4280ce6454fed6 100644 (file)
@@ -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')
     )
   })