test: cover new pool methods
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Mon, 18 Sep 2023 19:56:50 +0000 (21:56 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Mon, 18 Sep 2023 19:56:50 +0000 (21:56 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
docs/api.md
src/pools/abstract-pool.ts
src/worker/abstract-worker.ts
tests/pools/abstract/abstract-pool.test.js
tests/worker/abstract-worker.test.js

index 8e9d59cd68eef55bd06076e6e3f9f78e62425c13..8e3c77076f231bda67064b51eba22cd4150c3d77 100644 (file)
@@ -8,7 +8,11 @@
   - [`pool.execute(data, name, transferList)`](#poolexecutedata-name-transferlist)
   - [`pool.start()`](#poolstart)
   - [`pool.destroy()`](#pooldestroy)
+  - [`pool.hasTaskFunction(name)`](#poolhastaskfunctionname)
+  - [`pool.addTaskFunction(name, fn)`](#pooladdtaskfunctionname-fn)
+  - [`pool.removeTaskFunction(name)`](#poolremovetaskfunctionname)
   - [`pool.listTaskFunctionNames()`](#poollisttaskfunctionnames)
+  - [`pool.setDefaultTaskFunction(name)`](#poolsetdefaulttaskfunctionname)
   - [`PoolOptions`](#pooloptions)
     - [`ThreadPoolOptions extends PoolOptions`](#threadpooloptions-extends-pooloptions)
     - [`ClusterPoolOptions extends PoolOptions`](#clusterpooloptions-extends-pooloptions)
@@ -57,10 +61,29 @@ This method is available on both pool implementations and will call the terminat
 
 This method is available on both pool implementations and returns a boolean.
 
+### `pool.addTaskFunction(name, fn)`
+
+`name` (mandatory) The task function name.
+`fn` (mandatory) The task function.
+
+This method is available on both pool implementations and returns a boolean promise.
+
+### `pool.removeTaskFunction(name)`
+
+`name` (mandatory) The task function name.
+
+This method is available on both pool implementations and returns a boolean promise.
+
 ### `pool.listTaskFunctionNames()`
 
 This method is available on both pool implementations and returns an array of the task function names.
 
+### `pool.setDefaultTaskFunction(name)`
+
+`name` (mandatory) The task function name.
+
+This method is available on both pool implementations and returns a boolean promise.
+
 ### `PoolOptions`
 
 An object with these properties:
index 3d10391c17748cdd63473c4afae7630665023008..7be2cef51c8f11646b5f43174de7abe3ea43a82c 100644 (file)
@@ -858,6 +858,11 @@ export abstract class AbstractPool<
 
   /** @inheritDoc */
   public async removeTaskFunction (name: string): Promise<boolean> {
+    if (!this.taskFunctions.has(name)) {
+      throw new Error(
+        'Cannot remove a task function that does not exist on the pool side'
+      )
+    }
     this.taskFunctions.delete(name)
     return await this.sendTaskFunctionOperationToWorkers({
       taskFunctionOperation: 'remove',
index bc62ade55ef15efac79c8c9e8835a45cb697aa40..8bbd07a713c2a30c7f4614012350de54ed69bf55 100644 (file)
@@ -326,6 +326,7 @@ export abstract class AbstractWorker<
         DEFAULT_TASK_NAME,
         this.taskFunctions.get(name) as TaskFunction<Data, Response>
       )
+      this.sendTaskFunctionNamesToMainWorker()
       return { status: true }
     } catch (error) {
       return { status: false, error: error as Error }
@@ -376,7 +377,7 @@ export abstract class AbstractWorker<
   protected handleTaskFunctionOperationMessage (
     message: MessageValue<Data>
   ): void {
-    const { taskFunctionOperation, taskFunction, taskFunctionName } = message
+    const { taskFunctionOperation, taskFunctionName, taskFunction } = message
     let response!: TaskFunctionOperationReturnType
     if (taskFunctionOperation === 'add') {
       response = this.addTaskFunction(
index 9dca322ecf036abf8ee77be3dcc7a9bcf7354e1b..5c27a4b6e35469dfccc8bc71600a147dd0ac3475 100644 (file)
@@ -1243,6 +1243,111 @@ describe('Abstract pool test suite', () => {
     await pool.destroy()
   })
 
+  it('Verify that hasTaskFunction() is working', async () => {
+    const dynamicThreadPool = new DynamicThreadPool(
+      Math.floor(numberOfWorkers / 2),
+      numberOfWorkers,
+      './tests/worker-files/thread/testMultipleTaskFunctionsWorker.js'
+    )
+    await waitPoolEvents(dynamicThreadPool, PoolEvents.ready, 1)
+    expect(dynamicThreadPool.hasTaskFunction(DEFAULT_TASK_NAME)).toBe(true)
+    expect(dynamicThreadPool.hasTaskFunction('jsonIntegerSerialization')).toBe(
+      true
+    )
+    expect(dynamicThreadPool.hasTaskFunction('factorial')).toBe(true)
+    expect(dynamicThreadPool.hasTaskFunction('fibonacci')).toBe(true)
+    expect(dynamicThreadPool.hasTaskFunction('unknown')).toBe(false)
+    await dynamicThreadPool.destroy()
+    const fixedClusterPool = new FixedClusterPool(
+      numberOfWorkers,
+      './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.js'
+    )
+    await waitPoolEvents(fixedClusterPool, PoolEvents.ready, 1)
+    expect(fixedClusterPool.hasTaskFunction(DEFAULT_TASK_NAME)).toBe(true)
+    expect(fixedClusterPool.hasTaskFunction('jsonIntegerSerialization')).toBe(
+      true
+    )
+    expect(fixedClusterPool.hasTaskFunction('factorial')).toBe(true)
+    expect(fixedClusterPool.hasTaskFunction('fibonacci')).toBe(true)
+    expect(fixedClusterPool.hasTaskFunction('unknown')).toBe(false)
+    await fixedClusterPool.destroy()
+  })
+
+  it('Verify that addTaskFunction() is working', async () => {
+    const dynamicThreadPool = new DynamicThreadPool(
+      Math.floor(numberOfWorkers / 2),
+      numberOfWorkers,
+      './tests/worker-files/thread/testWorker.js'
+    )
+    await waitPoolEvents(dynamicThreadPool, PoolEvents.ready, 1)
+    expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([
+      DEFAULT_TASK_NAME,
+      'test'
+    ])
+    const echoTaskFunction = data => {
+      return data
+    }
+    await expect(
+      dynamicThreadPool.addTaskFunction('echo', echoTaskFunction)
+    ).resolves.toBe(true)
+    expect(dynamicThreadPool.taskFunctions.size).toBe(1)
+    expect(dynamicThreadPool.taskFunctions.get('echo')).toStrictEqual(
+      echoTaskFunction
+    )
+    expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([
+      DEFAULT_TASK_NAME,
+      'test',
+      'echo'
+    ])
+    const taskFunctionData = { test: 'test' }
+    const echoResult = await dynamicThreadPool.execute(taskFunctionData, 'echo')
+    expect(echoResult).toStrictEqual(taskFunctionData)
+    await dynamicThreadPool.destroy()
+  })
+
+  it('Verify that removeTaskFunction() is working', async () => {
+    const dynamicThreadPool = new DynamicThreadPool(
+      Math.floor(numberOfWorkers / 2),
+      numberOfWorkers,
+      './tests/worker-files/thread/testWorker.js'
+    )
+    await waitPoolEvents(dynamicThreadPool, PoolEvents.ready, 1)
+    expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([
+      DEFAULT_TASK_NAME,
+      'test'
+    ])
+    await expect(
+      dynamicThreadPool.removeTaskFunction('test')
+    ).rejects.toThrowError(
+      new Error(
+        'Cannot remove a task function that does not exist on the pool side'
+      )
+    )
+    const echoTaskFunction = data => {
+      return data
+    }
+    await dynamicThreadPool.addTaskFunction('echo', echoTaskFunction)
+    expect(dynamicThreadPool.taskFunctions.size).toBe(1)
+    expect(dynamicThreadPool.taskFunctions.get('echo')).toStrictEqual(
+      echoTaskFunction
+    )
+    expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([
+      DEFAULT_TASK_NAME,
+      'test',
+      'echo'
+    ])
+    await expect(dynamicThreadPool.removeTaskFunction('echo')).resolves.toBe(
+      true
+    )
+    expect(dynamicThreadPool.taskFunctions.size).toBe(0)
+    expect(dynamicThreadPool.taskFunctions.get('echo')).toBeUndefined()
+    expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([
+      DEFAULT_TASK_NAME,
+      'test'
+    ])
+    await dynamicThreadPool.destroy()
+  })
+
   it('Verify that listTaskFunctionNames() is working', async () => {
     const dynamicThreadPool = new DynamicThreadPool(
       Math.floor(numberOfWorkers / 2),
@@ -1256,6 +1361,7 @@ describe('Abstract pool test suite', () => {
       'factorial',
       'fibonacci'
     ])
+    await dynamicThreadPool.destroy()
     const fixedClusterPool = new FixedClusterPool(
       numberOfWorkers,
       './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.js'
@@ -1267,38 +1373,40 @@ describe('Abstract pool test suite', () => {
       'factorial',
       'fibonacci'
     ])
-    await dynamicThreadPool.destroy()
     await fixedClusterPool.destroy()
   })
 
-  it('Verify that hasTaskFunction() is working', async () => {
+  it('Verify that setDefaultTaskFunction() is working', async () => {
     const dynamicThreadPool = new DynamicThreadPool(
       Math.floor(numberOfWorkers / 2),
       numberOfWorkers,
       './tests/worker-files/thread/testMultipleTaskFunctionsWorker.js'
     )
     await waitPoolEvents(dynamicThreadPool, PoolEvents.ready, 1)
-    expect(dynamicThreadPool.hasTaskFunction(DEFAULT_TASK_NAME)).toBe(true)
-    expect(dynamicThreadPool.hasTaskFunction('jsonIntegerSerialization')).toBe(
-      true
-    )
-    expect(dynamicThreadPool.hasTaskFunction('factorial')).toBe(true)
-    expect(dynamicThreadPool.hasTaskFunction('fibonacci')).toBe(true)
-    expect(dynamicThreadPool.hasTaskFunction('unknown')).toBe(false)
-    const fixedClusterPool = new FixedClusterPool(
-      numberOfWorkers,
-      './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.js'
-    )
-    await waitPoolEvents(fixedClusterPool, PoolEvents.ready, 1)
-    expect(dynamicThreadPool.hasTaskFunction(DEFAULT_TASK_NAME)).toBe(true)
-    expect(dynamicThreadPool.hasTaskFunction('jsonIntegerSerialization')).toBe(
-      true
-    )
-    expect(dynamicThreadPool.hasTaskFunction('factorial')).toBe(true)
-    expect(dynamicThreadPool.hasTaskFunction('fibonacci')).toBe(true)
-    expect(dynamicThreadPool.hasTaskFunction('unknown')).toBe(false)
-    await dynamicThreadPool.destroy()
-    await fixedClusterPool.destroy()
+    expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([
+      DEFAULT_TASK_NAME,
+      'jsonIntegerSerialization',
+      'factorial',
+      'fibonacci'
+    ])
+    await expect(
+      dynamicThreadPool.setDefaultTaskFunction('factorial')
+    ).resolves.toBe(true)
+    expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([
+      DEFAULT_TASK_NAME,
+      'factorial',
+      'jsonIntegerSerialization',
+      'fibonacci'
+    ])
+    await expect(
+      dynamicThreadPool.setDefaultTaskFunction('fibonacci')
+    ).resolves.toBe(true)
+    expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([
+      DEFAULT_TASK_NAME,
+      'fibonacci',
+      'jsonIntegerSerialization',
+      'factorial'
+    ])
   })
 
   it('Verify that multiple task functions worker is working', async () => {
index 13f3ae17aa70528bc14d259472b911f0c163bc02..200b05acdff0f26a29c0eb4e2e760a64448935f5 100644 (file)
@@ -200,7 +200,7 @@ describe('Abstract worker test suite', () => {
     expect(killHandlerStub.calledOnce).toBe(true)
   })
 
-  it('Verify that handleError() method works properly', () => {
+  it('Verify that handleError() method is working properly', () => {
     const error = new Error('Error as an error')
     const worker = new ClusterWorker(() => {})
     expect(worker.handleError(error)).not.toBeInstanceOf(Error)
@@ -215,7 +215,7 @@ describe('Abstract worker test suite', () => {
     ).toThrowError('Main worker not set')
   })
 
-  it('Verify that hasTaskFunction() works', () => {
+  it('Verify that hasTaskFunction() is working', () => {
     const fn1 = () => {
       return 1
     }
@@ -239,7 +239,7 @@ describe('Abstract worker test suite', () => {
     expect(worker.hasTaskFunction('fn3')).toStrictEqual({ status: false })
   })
 
-  it('Verify that addTaskFunction() works', () => {
+  it('Verify that addTaskFunction() is working', () => {
     const fn1 = () => {
       return 1
     }
@@ -292,7 +292,7 @@ describe('Abstract worker test suite', () => {
     )
   })
 
-  it('Verify that removeTaskFunction() works', () => {
+  it('Verify that removeTaskFunction() is working', () => {
     const fn1 = () => {
       return 1
     }
@@ -339,7 +339,7 @@ describe('Abstract worker test suite', () => {
     expect(worker.getMainWorker().send.calledOnce).toBe(true)
   })
 
-  it('Verify that listTaskFunctionNames() works', () => {
+  it('Verify that listTaskFunctionNames() is working', () => {
     const fn1 = () => {
       return 1
     }
@@ -354,7 +354,7 @@ describe('Abstract worker test suite', () => {
     ])
   })
 
-  it('Verify that setDefaultTaskFunction() works', () => {
+  it('Verify that setDefaultTaskFunction() is working', () => {
     const fn1 = () => {
       return 1
     }