fix: ensure no task can be executed on destroyed pool
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 23 Aug 2023 11:02:53 +0000 (13:02 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 23 Aug 2023 11:02:53 +0000 (13:02 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
CHANGELOG.md
src/pools/abstract-pool.ts

index 0fe43abdff91300f83c2d96a3fef74b238a534fe..c1e6599216e5b4981b4c32ba2d77a07d032885d8 100644 (file)
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## [Unreleased]
 
+### Fixed
+
+- Ensure no task can be executed when the pool is destroyed.
+
 ### Added
 
 - Add `queueMaxSize` option to tasks queue options.
index f0304364e8770f729f7dbb4100069e146f8dda72..7310e9efa2abd32e58bbb6744049e7f1573dbc34 100644 (file)
@@ -93,6 +93,10 @@ export abstract class AbstractPool<
    * Whether the pool is starting or not.
    */
   private readonly starting: boolean
+  /**
+   * Whether the pool is started or not.
+   */
+  private started: boolean
   /**
    * The start timestamp of the pool.
    */
@@ -141,6 +145,7 @@ export abstract class AbstractPool<
     this.starting = true
     this.startPool()
     this.starting = false
+    this.started = true
 
     this.startTimestamp = performance.now()
   }
@@ -723,6 +728,9 @@ export abstract class AbstractPool<
     transferList?: TransferListItem[]
   ): Promise<Response> {
     return await new Promise<Response>((resolve, reject) => {
+      if (!this.started) {
+        reject(new Error('Cannot execute a task on destroyed pool'))
+      }
       if (name != null && typeof name !== 'string') {
         reject(new TypeError('name argument must be a string'))
       }
@@ -783,6 +791,7 @@ export abstract class AbstractPool<
       })
     )
     this.emitter?.emit(PoolEvents.destroy, this.info)
+    this.started = false
   }
 
   protected async sendKillMessageToWorker (
@@ -1050,7 +1059,11 @@ export abstract class AbstractPool<
       workerInfo.ready = false
       this.workerNodes[workerNodeKey].closeChannel()
       this.emitter?.emit(PoolEvents.error, error)
-      if (this.opts.restartWorkerOnError === true && !this.starting) {
+      if (
+        this.opts.restartWorkerOnError === true &&
+        !this.starting &&
+        this.started
+      ) {
         if (workerInfo.dynamic) {
           this.createAndSetupDynamicWorkerNode()
         } else {