test: test for wait node readiness in dynamic pool
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Tue, 19 Dec 2023 17:56:54 +0000 (18:56 +0100)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Tue, 19 Dec 2023 17:56:54 +0000 (18:56 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
src/pools/selection-strategies/worker-choice-strategy-context.ts
tests/pools/selection-strategies/selection-strategies.test.mjs
tests/pools/selection-strategies/worker-choice-strategy-context.test.mjs

index d6a6e26d27e87fbb263a9ef5b61e5c1745b60950..14e734fd6a50bd40647ebc9af012dc77d24654ac 100644 (file)
@@ -170,7 +170,7 @@ export class WorkerChoiceStrategyContext<
       this.workerChoiceStrategy
     ) as IWorkerChoiceStrategy
     if (!workerChoiceStrategy.hasPoolWorkerNodesReady()) {
-      // wait for a worker node to be ready without blocking the event loop
+      return this.execute()
     }
     return this.executeStrategy(workerChoiceStrategy)
   }
index b7597b4c0c71d0f326fb866dbebb1d277474667f..127377a26118c5d5be57cf98661eb9139fe5d81f 100644 (file)
@@ -7,6 +7,7 @@ import {
   WorkerChoiceStrategies
 } from '../../../lib/index.js'
 import { CircularArray } from '../../../lib/circular-array.js'
+import { sleep } from '../../test-utils.js'
 
 describe('Selection strategies test suite', () => {
   const min = 0
@@ -174,6 +175,26 @@ describe('Selection strategies test suite', () => {
     await pool.destroy()
   })
 
+  it('Verify strategies wait for worker node readiness in dynamic pool', async () => {
+    const pool = new DynamicThreadPool(
+      min,
+      max,
+      './tests/worker-files/thread/testWorker.mjs'
+    )
+    await sleep(600)
+    expect(pool.starting).toBe(false)
+    expect(pool.workerNodes.length).toBe(min)
+    const maxMultiplier = 10000
+    const promises = new Set()
+    for (let i = 0; i < max * maxMultiplier; i++) {
+      promises.add(pool.execute())
+    }
+    await Promise.all(promises)
+    expect(pool.workerNodes.length).toBe(max)
+    // We need to clean up the resources after our test
+    await pool.destroy()
+  })
+
   it('Verify ROUND_ROBIN strategy default policy', async () => {
     const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
     let pool = new FixedThreadPool(
index bb8c7fefb3a1567919af0736f698c6e6f4a55359..96281a9563bf853d207156984fdf9f2938579213 100644 (file)
@@ -131,12 +131,6 @@ describe('Worker choice strategy context test suite', () => {
           .returns(false)
           .onCall(4)
           .returns(false)
-          .onCall(6)
-          .returns(false)
-          .onCall(7)
-          .returns(false)
-          .onCall(8)
-          .returns(false)
           .returns(true),
         choose: stub().returns(1)
       }
@@ -153,7 +147,7 @@ describe('Worker choice strategy context test suite', () => {
       workerChoiceStrategyContext.workerChoiceStrategies.get(
         workerChoiceStrategyContext.workerChoiceStrategy
       ).hasPoolWorkerNodesReady.callCount
-    ).toBe(12)
+    ).toBe(6)
     expect(
       workerChoiceStrategyContext.workerChoiceStrategies.get(
         workerChoiceStrategyContext.workerChoiceStrategy
@@ -162,7 +156,7 @@ describe('Worker choice strategy context test suite', () => {
     expect(chosenWorkerKey).toBe(1)
   })
 
-  it('Verify that execute() throws error if worker choice strategy consecutive executions has been reached', () => {
+  it('Verify that execute() throws error if worker choice strategy recursion reach the maximum depth', () => {
     const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
       fixedPool
     )
@@ -181,9 +175,7 @@ describe('Worker choice strategy context test suite', () => {
       workerChoiceStrategyStub
     )
     expect(() => workerChoiceStrategyContext.execute()).toThrow(
-      new RangeError(
-        'Worker choice strategy consecutive executions has exceeded the maximum of 10000'
-      )
+      new RangeError('Maximum call stack size exceeded')
     )
   })