refactor: reorder methods
[poolifier.git] / src / worker / abstract-worker.ts
index 7563e97bf5cadf01b296ed1811def122d6e875dc..fbf99ab8f1dfffe8936b4f25140c3d9597772d3b 100644 (file)
@@ -1,7 +1,12 @@
 import { AsyncResource } from 'node:async_hooks'
 import type { Worker } from 'node:cluster'
 import type { MessagePort } from 'node:worker_threads'
-import type { MessageValue } from '../utility-types'
+import type {
+  MessageValue,
+  WorkerAsyncFunction,
+  WorkerFunction,
+  WorkerSyncFunction
+} from '../utility-types'
 import { EMPTY_FUNCTION } from '../utils'
 import type { KillBehavior, WorkerOptions } from './worker-options'
 import { KillBehaviors } from './worker-options'
@@ -41,7 +46,7 @@ export abstract class AbstractWorker<
   public constructor (
     type: string,
     protected readonly isMain: boolean,
-    fn: (data: Data) => Response,
+    fn: WorkerFunction<Data, Response>,
     protected mainWorker: MainWorker | undefined | null,
     protected readonly opts: WorkerOptions = {
       /**
@@ -56,8 +61,8 @@ export abstract class AbstractWorker<
     }
   ) {
     super(type)
-    this.checkFunctionInput(fn)
     this.checkWorkerOptions(this.opts)
+    this.checkFunctionInput(fn)
     if (!this.isMain) {
       this.lastTaskTimestamp = performance.now()
       this.aliveInterval = setInterval(
@@ -75,6 +80,30 @@ export abstract class AbstractWorker<
     )
   }
 
+  private checkWorkerOptions (opts: WorkerOptions): void {
+    this.opts.killBehavior = opts.killBehavior ?? DEFAULT_KILL_BEHAVIOR
+    this.opts.maxInactiveTime =
+      opts.maxInactiveTime ?? DEFAULT_MAX_INACTIVE_TIME
+    this.opts.async = opts.async ?? false
+  }
+
+  /**
+   * Checks if the `fn` parameter is passed to the constructor.
+   *
+   * @param fn - The function that should be defined.
+   */
+  private checkFunctionInput (fn: WorkerFunction<Data, Response>): void {
+    if (fn == null) throw new Error('fn parameter is mandatory')
+    if (typeof fn !== 'function') {
+      throw new TypeError('fn parameter is not a function')
+    }
+    if (fn.constructor.name === 'AsyncFunction' && this.opts.async === false) {
+      throw new Error(
+        'fn parameter is an async function, please set the async option to true'
+      )
+    }
+  }
+
   /**
    * Worker message listener.
    *
@@ -83,7 +112,7 @@ export abstract class AbstractWorker<
    */
   protected messageListener (
     message: MessageValue<Data, MainWorker>,
-    fn: (data: Data) => Response
+    fn: WorkerFunction<Data, Response>
   ): void {
     if (message.id != null && message.data != null) {
       // Task message received
@@ -102,25 +131,6 @@ export abstract class AbstractWorker<
     }
   }
 
-  private checkWorkerOptions (opts: WorkerOptions): void {
-    this.opts.killBehavior = opts.killBehavior ?? DEFAULT_KILL_BEHAVIOR
-    this.opts.maxInactiveTime =
-      opts.maxInactiveTime ?? DEFAULT_MAX_INACTIVE_TIME
-    this.opts.async = opts.async ?? false
-  }
-
-  /**
-   * Checks if the `fn` parameter is passed to the constructor.
-   *
-   * @param fn - The function that should be defined.
-   */
-  private checkFunctionInput (fn: (data: Data) => Response): void {
-    if (fn == null) throw new Error('fn parameter is mandatory')
-    if (typeof fn !== 'function') {
-      throw new TypeError('fn parameter is not a function')
-    }
-  }
-
   /**
    * Returns the main worker.
    *
@@ -169,7 +179,7 @@ export abstract class AbstractWorker<
    * @param message - Input data for the given function.
    */
   protected run (
-    fn: (data?: Data) => Response,
+    fn: WorkerSyncFunction<Data, Response>,
     message: MessageValue<Data>
   ): void {
     try {
@@ -196,7 +206,7 @@ export abstract class AbstractWorker<
    * @param message - Input data for the given function.
    */
   protected runAsync (
-    fn: (data?: Data) => Promise<Response>,
+    fn: WorkerAsyncFunction<Data, Response>,
     message: MessageValue<Data>
   ): void {
     const startTimestamp = performance.now()