1 const { expect
} = require('expect')
9 WorkerChoiceStrategies
,
11 } = require('../../../lib')
12 const { CircularArray
} = require('../../../lib/circular-array')
13 const { Queue
} = require('../../../lib/queue')
14 const { version
} = require('../../../package.json')
15 const { waitPoolEvents
} = require('../../test-utils')
17 describe('Abstract pool test suite', () => {
18 const numberOfWorkers
= 2
19 class StubPoolWithIsMain
extends FixedThreadPool
{
25 it('Simulate pool creation from a non main thread/process', () => {
28 new StubPoolWithIsMain(
30 './tests/worker-files/thread/testWorker.js',
32 errorHandler
: (e
) => console
.error(e
)
36 'Cannot start a pool from a worker with the same type as the pool'
40 it('Verify that filePath is checked', () => {
41 const expectedError
= new Error(
42 'Please specify a file with a worker implementation'
44 expect(() => new FixedThreadPool(numberOfWorkers
)).toThrowError(
47 expect(() => new FixedThreadPool(numberOfWorkers
, '')).toThrowError(
50 expect(() => new FixedThreadPool(numberOfWorkers
, 0)).toThrowError(
53 expect(() => new FixedThreadPool(numberOfWorkers
, true)).toThrowError(
57 () => new FixedThreadPool(numberOfWorkers
, './dummyWorker.ts')
58 ).toThrowError(new Error("Cannot find the worker file './dummyWorker.ts'"))
61 it('Verify that numberOfWorkers is checked', () => {
62 expect(() => new FixedThreadPool()).toThrowError(
63 'Cannot instantiate a pool without specifying the number of workers'
67 it('Verify that a negative number of workers is checked', () => {
70 new FixedClusterPool(-1, './tests/worker-files/cluster/testWorker.js')
73 'Cannot instantiate a pool with a negative number of workers'
78 it('Verify that a non integer number of workers is checked', () => {
81 new FixedThreadPool(0.25, './tests/worker-files/thread/testWorker.js')
84 'Cannot instantiate a pool with a non safe integer number of workers'
89 it('Verify that dynamic pool sizing is checked', () => {
92 new DynamicClusterPool(
95 './tests/worker-files/cluster/testWorker.js'
99 'Cannot instantiate a dynamic pool without specifying the maximum pool size'
104 new DynamicThreadPool(
107 './tests/worker-files/thread/testWorker.js'
111 'Cannot instantiate a pool with a non safe integer number of workers'
116 new DynamicClusterPool(
119 './tests/worker-files/cluster/testWorker.js'
123 'Cannot instantiate a dynamic pool with a non safe integer maximum pool size'
128 new DynamicThreadPool(2, 1, './tests/worker-files/thread/testWorker.js')
131 'Cannot instantiate a dynamic pool with a maximum pool size inferior to the minimum pool size'
136 new DynamicClusterPool(
139 './tests/worker-files/cluster/testWorker.js'
143 'Cannot instantiate a dynamic pool with a minimum pool size equal to the maximum pool size. Use a fixed pool instead'
148 new DynamicThreadPool(0, 0, './tests/worker-files/thread/testWorker.js')
151 'Cannot instantiate a dynamic pool with a maximum pool size equal to zero'
156 it('Verify that pool options are checked', async () => {
157 let pool
= new FixedThreadPool(
159 './tests/worker-files/thread/testWorker.js'
161 expect(pool
.emitter
).toBeDefined()
162 expect(pool
.opts
.enableEvents
).toBe(true)
163 expect(pool
.opts
.restartWorkerOnError
).toBe(true)
164 expect(pool
.opts
.enableTasksQueue
).toBe(false)
165 expect(pool
.opts
.tasksQueueOptions
).toBeUndefined()
166 expect(pool
.opts
.workerChoiceStrategy
).toBe(
167 WorkerChoiceStrategies
.ROUND_ROBIN
169 expect(pool
.opts
.workerChoiceStrategyOptions
).toStrictEqual({
171 runTime
: { median
: false },
172 waitTime
: { median
: false },
173 elu
: { median
: false }
175 expect(pool
.workerChoiceStrategyContext
.opts
).toStrictEqual({
177 runTime
: { median
: false },
178 waitTime
: { median
: false },
179 elu
: { median
: false }
181 expect(pool
.opts
.messageHandler
).toBeUndefined()
182 expect(pool
.opts
.errorHandler
).toBeUndefined()
183 expect(pool
.opts
.onlineHandler
).toBeUndefined()
184 expect(pool
.opts
.exitHandler
).toBeUndefined()
186 const testHandler
= () => console
.info('test handler executed')
187 pool
= new FixedThreadPool(
189 './tests/worker-files/thread/testWorker.js',
191 workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
,
192 workerChoiceStrategyOptions
: {
193 runTime
: { median
: true },
194 weights
: { 0: 300, 1: 200 }
197 restartWorkerOnError
: false,
198 enableTasksQueue
: true,
199 tasksQueueOptions
: { concurrency
: 2 },
200 messageHandler
: testHandler
,
201 errorHandler
: testHandler
,
202 onlineHandler
: testHandler
,
203 exitHandler
: testHandler
206 expect(pool
.emitter
).toBeUndefined()
207 expect(pool
.opts
.enableEvents
).toBe(false)
208 expect(pool
.opts
.restartWorkerOnError
).toBe(false)
209 expect(pool
.opts
.enableTasksQueue
).toBe(true)
210 expect(pool
.opts
.tasksQueueOptions
).toStrictEqual({ concurrency
: 2 })
211 expect(pool
.opts
.workerChoiceStrategy
).toBe(
212 WorkerChoiceStrategies
.LEAST_USED
214 expect(pool
.opts
.workerChoiceStrategyOptions
).toStrictEqual({
216 runTime
: { median
: true },
217 waitTime
: { median
: false },
218 elu
: { median
: false },
219 weights
: { 0: 300, 1: 200 }
221 expect(pool
.workerChoiceStrategyContext
.opts
).toStrictEqual({
223 runTime
: { median
: true },
224 waitTime
: { median
: false },
225 elu
: { median
: false },
226 weights
: { 0: 300, 1: 200 }
228 expect(pool
.opts
.messageHandler
).toStrictEqual(testHandler
)
229 expect(pool
.opts
.errorHandler
).toStrictEqual(testHandler
)
230 expect(pool
.opts
.onlineHandler
).toStrictEqual(testHandler
)
231 expect(pool
.opts
.exitHandler
).toStrictEqual(testHandler
)
235 it('Verify that pool options are validated', async () => {
240 './tests/worker-files/thread/testWorker.js',
242 workerChoiceStrategy
: 'invalidStrategy'
246 new Error("Invalid worker choice strategy 'invalidStrategy'")
252 './tests/worker-files/thread/testWorker.js',
254 workerChoiceStrategyOptions
: { weights
: {} }
259 'Invalid worker choice strategy options: must have a weight for each worker node'
266 './tests/worker-files/thread/testWorker.js',
268 workerChoiceStrategyOptions
: { measurement
: 'invalidMeasurement' }
273 "Invalid worker choice strategy options: invalid measurement 'invalidMeasurement'"
280 './tests/worker-files/thread/testWorker.js',
282 enableTasksQueue
: true,
283 tasksQueueOptions
: { concurrency
: 0 }
288 'Invalid worker tasks concurrency: 0 is a negative integer or zero'
295 './tests/worker-files/thread/testWorker.js',
297 enableTasksQueue
: true,
298 tasksQueueOptions
: 'invalidTasksQueueOptions'
302 new TypeError('Invalid tasks queue options: must be a plain object')
308 './tests/worker-files/thread/testWorker.js',
310 enableTasksQueue
: true,
311 tasksQueueOptions
: { concurrency
: 0.2 }
315 new TypeError('Invalid worker tasks concurrency: must be an integer')
319 it('Verify that pool worker choice strategy options can be set', async () => {
320 const pool
= new FixedThreadPool(
322 './tests/worker-files/thread/testWorker.js',
323 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
325 expect(pool
.opts
.workerChoiceStrategyOptions
).toStrictEqual({
327 runTime
: { median
: false },
328 waitTime
: { median
: false },
329 elu
: { median
: false }
331 expect(pool
.workerChoiceStrategyContext
.opts
).toStrictEqual({
333 runTime
: { median
: false },
334 waitTime
: { median
: false },
335 elu
: { median
: false }
337 for (const [, workerChoiceStrategy
] of pool
.workerChoiceStrategyContext
338 .workerChoiceStrategies
) {
339 expect(workerChoiceStrategy
.opts
).toStrictEqual({
341 runTime
: { median
: false },
342 waitTime
: { median
: false },
343 elu
: { median
: false }
347 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
365 pool
.setWorkerChoiceStrategyOptions({
366 runTime
: { median
: true },
367 elu
: { median
: true }
369 expect(pool
.opts
.workerChoiceStrategyOptions
).toStrictEqual({
371 runTime
: { median
: true },
372 waitTime
: { median
: false },
373 elu
: { median
: true }
375 expect(pool
.workerChoiceStrategyContext
.opts
).toStrictEqual({
377 runTime
: { median
: true },
378 waitTime
: { median
: false },
379 elu
: { median
: true }
381 for (const [, workerChoiceStrategy
] of pool
.workerChoiceStrategyContext
382 .workerChoiceStrategies
) {
383 expect(workerChoiceStrategy
.opts
).toStrictEqual({
385 runTime
: { median
: true },
386 waitTime
: { median
: false },
387 elu
: { median
: true }
391 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
409 pool
.setWorkerChoiceStrategyOptions({
410 runTime
: { median
: false },
411 elu
: { median
: false }
413 expect(pool
.opts
.workerChoiceStrategyOptions
).toStrictEqual({
415 runTime
: { median
: false },
416 waitTime
: { median
: false },
417 elu
: { median
: false }
419 expect(pool
.workerChoiceStrategyContext
.opts
).toStrictEqual({
421 runTime
: { median
: false },
422 waitTime
: { median
: false },
423 elu
: { median
: false }
425 for (const [, workerChoiceStrategy
] of pool
.workerChoiceStrategyContext
426 .workerChoiceStrategies
) {
427 expect(workerChoiceStrategy
.opts
).toStrictEqual({
429 runTime
: { median
: false },
430 waitTime
: { median
: false },
431 elu
: { median
: false }
435 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
454 pool
.setWorkerChoiceStrategyOptions('invalidWorkerChoiceStrategyOptions')
457 'Invalid worker choice strategy options: must be a plain object'
461 pool
.setWorkerChoiceStrategyOptions({ weights
: {} })
464 'Invalid worker choice strategy options: must have a weight for each worker node'
468 pool
.setWorkerChoiceStrategyOptions({ measurement
: 'invalidMeasurement' })
471 "Invalid worker choice strategy options: invalid measurement 'invalidMeasurement'"
477 it('Verify that pool tasks queue can be enabled/disabled', async () => {
478 const pool
= new FixedThreadPool(
480 './tests/worker-files/thread/testWorker.js'
482 expect(pool
.opts
.enableTasksQueue
).toBe(false)
483 expect(pool
.opts
.tasksQueueOptions
).toBeUndefined()
484 pool
.enableTasksQueue(true)
485 expect(pool
.opts
.enableTasksQueue
).toBe(true)
486 expect(pool
.opts
.tasksQueueOptions
).toStrictEqual({ concurrency
: 1 })
487 pool
.enableTasksQueue(true, { concurrency
: 2 })
488 expect(pool
.opts
.enableTasksQueue
).toBe(true)
489 expect(pool
.opts
.tasksQueueOptions
).toStrictEqual({ concurrency
: 2 })
490 pool
.enableTasksQueue(false)
491 expect(pool
.opts
.enableTasksQueue
).toBe(false)
492 expect(pool
.opts
.tasksQueueOptions
).toBeUndefined()
496 it('Verify that pool tasks queue options can be set', async () => {
497 const pool
= new FixedThreadPool(
499 './tests/worker-files/thread/testWorker.js',
500 { enableTasksQueue
: true }
502 expect(pool
.opts
.tasksQueueOptions
).toStrictEqual({ concurrency
: 1 })
503 pool
.setTasksQueueOptions({ concurrency
: 2 })
504 expect(pool
.opts
.tasksQueueOptions
).toStrictEqual({ concurrency
: 2 })
506 pool
.setTasksQueueOptions('invalidTasksQueueOptions')
508 new TypeError('Invalid tasks queue options: must be a plain object')
510 expect(() => pool
.setTasksQueueOptions({ concurrency
: 0 })).toThrowError(
512 'Invalid worker tasks concurrency: 0 is a negative integer or zero'
515 expect(() => pool
.setTasksQueueOptions({ concurrency
: -1 })).toThrowError(
517 'Invalid worker tasks concurrency: -1 is a negative integer or zero'
520 expect(() => pool
.setTasksQueueOptions({ concurrency
: 0.2 })).toThrowError(
521 new TypeError('Invalid worker tasks concurrency: must be an integer')
526 it('Verify that pool info is set', async () => {
527 let pool
= new FixedThreadPool(
529 './tests/worker-files/thread/testWorker.js'
531 expect(pool
.info
).toStrictEqual({
533 type
: PoolTypes
.fixed
,
534 worker
: WorkerTypes
.thread
,
536 strategy
: WorkerChoiceStrategies
.ROUND_ROBIN
,
537 minSize
: numberOfWorkers
,
538 maxSize
: numberOfWorkers
,
539 workerNodes
: numberOfWorkers
,
540 idleWorkerNodes
: numberOfWorkers
,
547 pool
= new DynamicClusterPool(
548 Math
.floor(numberOfWorkers
/ 2),
550 './tests/worker-files/cluster/testWorker.js'
552 expect(pool
.info
).toStrictEqual({
554 type
: PoolTypes
.dynamic
,
555 worker
: WorkerTypes
.cluster
,
557 strategy
: WorkerChoiceStrategies
.ROUND_ROBIN
,
558 minSize
: Math
.floor(numberOfWorkers
/ 2),
559 maxSize
: numberOfWorkers
,
560 workerNodes
: Math
.floor(numberOfWorkers
/ 2),
561 idleWorkerNodes
: Math
.floor(numberOfWorkers
/ 2),
570 it('Verify that pool worker tasks usage are initialized', async () => {
571 const pool
= new FixedClusterPool(
573 './tests/worker-files/cluster/testWorker.js'
575 for (const workerNode
of pool
.workerNodes
) {
576 expect(workerNode
.usage
).toStrictEqual({
585 history
: expect
.any(CircularArray
)
588 history
: expect
.any(CircularArray
)
592 history
: expect
.any(CircularArray
)
595 history
: expect
.any(CircularArray
)
603 it('Verify that pool worker tasks queue are initialized', async () => {
604 let pool
= new FixedClusterPool(
606 './tests/worker-files/cluster/testWorker.js'
608 for (const workerNode
of pool
.workerNodes
) {
609 expect(workerNode
.tasksQueue
).toBeDefined()
610 expect(workerNode
.tasksQueue
).toBeInstanceOf(Queue
)
611 expect(workerNode
.tasksQueue
.size
).toBe(0)
612 expect(workerNode
.tasksQueue
.maxSize
).toBe(0)
615 pool
= new DynamicThreadPool(
616 Math
.floor(numberOfWorkers
/ 2),
618 './tests/worker-files/thread/testWorker.js'
620 for (const workerNode
of pool
.workerNodes
) {
621 expect(workerNode
.tasksQueue
).toBeDefined()
622 expect(workerNode
.tasksQueue
).toBeInstanceOf(Queue
)
623 expect(workerNode
.tasksQueue
.size
).toBe(0)
624 expect(workerNode
.tasksQueue
.maxSize
).toBe(0)
628 it('Verify that pool worker info are initialized', async () => {
629 let pool
= new FixedClusterPool(
631 './tests/worker-files/cluster/testWorker.js'
633 for (const workerNode
of pool
.workerNodes
) {
634 expect(workerNode
.info
).toStrictEqual({
635 id
: expect
.any(Number
),
636 type
: WorkerTypes
.cluster
,
642 pool
= new DynamicThreadPool(
643 Math
.floor(numberOfWorkers
/ 2),
645 './tests/worker-files/thread/testWorker.js'
647 for (const workerNode
of pool
.workerNodes
) {
648 expect(workerNode
.info
).toStrictEqual({
649 id
: expect
.any(Number
),
650 type
: WorkerTypes
.thread
,
657 it('Verify that pool worker tasks usage are computed', async () => {
658 const pool
= new FixedClusterPool(
660 './tests/worker-files/cluster/testWorker.js'
662 const promises
= new Set()
663 const maxMultiplier
= 2
664 for (let i
= 0; i
< numberOfWorkers
* maxMultiplier
; i
++) {
665 promises
.add(pool
.execute())
667 for (const workerNode
of pool
.workerNodes
) {
668 expect(workerNode
.usage
).toStrictEqual({
671 executing
: maxMultiplier
,
677 history
: expect
.any(CircularArray
)
680 history
: expect
.any(CircularArray
)
684 history
: expect
.any(CircularArray
)
687 history
: expect
.any(CircularArray
)
692 await Promise
.all(promises
)
693 for (const workerNode
of pool
.workerNodes
) {
694 expect(workerNode
.usage
).toStrictEqual({
696 executed
: maxMultiplier
,
703 history
: expect
.any(CircularArray
)
706 history
: expect
.any(CircularArray
)
710 history
: expect
.any(CircularArray
)
713 history
: expect
.any(CircularArray
)
721 it('Verify that pool worker tasks usage are reset at worker choice strategy change', async () => {
722 const pool
= new DynamicThreadPool(
723 Math
.floor(numberOfWorkers
/ 2),
725 './tests/worker-files/thread/testWorker.js'
727 const promises
= new Set()
728 const maxMultiplier
= 2
729 for (let i
= 0; i
< numberOfWorkers
* maxMultiplier
; i
++) {
730 promises
.add(pool
.execute())
732 await Promise
.all(promises
)
733 for (const workerNode
of pool
.workerNodes
) {
734 expect(workerNode
.usage
).toStrictEqual({
736 executed
: expect
.any(Number
),
743 history
: expect
.any(CircularArray
)
746 history
: expect
.any(CircularArray
)
750 history
: expect
.any(CircularArray
)
753 history
: expect
.any(CircularArray
)
757 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThan(0)
758 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(maxMultiplier
)
759 expect(workerNode
.usage
.runTime
.history
.length
).toBe(0)
760 expect(workerNode
.usage
.waitTime
.history
.length
).toBe(0)
761 expect(workerNode
.usage
.elu
.idle
.history
.length
).toBe(0)
762 expect(workerNode
.usage
.elu
.active
.history
.length
).toBe(0)
764 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
765 for (const workerNode
of pool
.workerNodes
) {
766 expect(workerNode
.usage
).toStrictEqual({
775 history
: expect
.any(CircularArray
)
778 history
: expect
.any(CircularArray
)
782 history
: expect
.any(CircularArray
)
785 history
: expect
.any(CircularArray
)
789 expect(workerNode
.usage
.runTime
.history
.length
).toBe(0)
790 expect(workerNode
.usage
.waitTime
.history
.length
).toBe(0)
791 expect(workerNode
.usage
.elu
.idle
.history
.length
).toBe(0)
792 expect(workerNode
.usage
.elu
.active
.history
.length
).toBe(0)
797 it("Verify that pool event emitter 'ready' event can register a callback", async () => {
798 const pool
= new DynamicClusterPool(
799 Math
.floor(numberOfWorkers
/ 2),
801 './tests/worker-files/cluster/testWorker.js'
805 pool
.emitter
.on(PoolEvents
.ready
, (info
) => {
809 await
waitPoolEvents(pool
, PoolEvents
.ready
, 1)
810 expect(poolReady
).toBe(1)
811 expect(poolInfo
).toStrictEqual({
813 type
: PoolTypes
.dynamic
,
814 worker
: WorkerTypes
.cluster
,
816 strategy
: WorkerChoiceStrategies
.ROUND_ROBIN
,
817 minSize
: expect
.any(Number
),
818 maxSize
: expect
.any(Number
),
819 workerNodes
: expect
.any(Number
),
820 idleWorkerNodes
: expect
.any(Number
),
821 busyWorkerNodes
: expect
.any(Number
),
822 executedTasks
: expect
.any(Number
),
823 executingTasks
: expect
.any(Number
),
824 failedTasks
: expect
.any(Number
)
829 it("Verify that pool event emitter 'busy' event can register a callback", async () => {
830 const pool
= new FixedThreadPool(
832 './tests/worker-files/thread/testWorker.js'
834 const promises
= new Set()
837 pool
.emitter
.on(PoolEvents
.busy
, (info
) => {
841 for (let i
= 0; i
< numberOfWorkers
* 2; i
++) {
842 promises
.add(pool
.execute())
844 await Promise
.all(promises
)
845 // The `busy` event is triggered when the number of submitted tasks at once reach the number of fixed pool workers.
846 // So in total numberOfWorkers + 1 times for a loop submitting up to numberOfWorkers * 2 tasks to the fixed pool.
847 expect(poolBusy
).toBe(numberOfWorkers
+ 1)
848 expect(poolInfo
).toStrictEqual({
850 type
: PoolTypes
.fixed
,
851 worker
: WorkerTypes
.thread
,
852 ready
: expect
.any(Boolean
),
853 strategy
: WorkerChoiceStrategies
.ROUND_ROBIN
,
854 minSize
: expect
.any(Number
),
855 maxSize
: expect
.any(Number
),
856 workerNodes
: expect
.any(Number
),
857 idleWorkerNodes
: expect
.any(Number
),
858 busyWorkerNodes
: expect
.any(Number
),
859 executedTasks
: expect
.any(Number
),
860 executingTasks
: expect
.any(Number
),
861 failedTasks
: expect
.any(Number
)
866 it("Verify that pool event emitter 'full' event can register a callback", async () => {
867 const pool
= new DynamicThreadPool(
868 Math
.floor(numberOfWorkers
/ 2),
870 './tests/worker-files/thread/testWorker.js'
872 const promises
= new Set()
875 pool
.emitter
.on(PoolEvents
.full
, (info
) => {
879 for (let i
= 0; i
< numberOfWorkers
* 2; i
++) {
880 promises
.add(pool
.execute())
882 await Promise
.all(promises
)
883 expect(poolFull
).toBe(1)
884 expect(poolInfo
).toStrictEqual({
886 type
: PoolTypes
.dynamic
,
887 worker
: WorkerTypes
.thread
,
888 ready
: expect
.any(Boolean
),
889 strategy
: WorkerChoiceStrategies
.ROUND_ROBIN
,
890 minSize
: expect
.any(Number
),
891 maxSize
: expect
.any(Number
),
892 workerNodes
: expect
.any(Number
),
893 idleWorkerNodes
: expect
.any(Number
),
894 busyWorkerNodes
: expect
.any(Number
),
895 executedTasks
: expect
.any(Number
),
896 executingTasks
: expect
.any(Number
),
897 failedTasks
: expect
.any(Number
)
902 it
.skip("Verify that pool event emitter 'backPressure' event can register a callback", async () => {
903 const pool
= new DynamicThreadPool(
904 Math
.floor(numberOfWorkers
/ 2),
906 './tests/worker-files/thread/testWorker.js',
908 enableTasksQueue
: true
911 const promises
= new Set()
912 let poolBackPressure
= 0
914 pool
.emitter
.on(PoolEvents
.backPressure
, (info
) => {
918 for (let i
= 0; i
< Math
.pow(numberOfWorkers
, 2); i
++) {
919 promises
.add(pool
.execute())
921 await Promise
.all(promises
)
922 expect(poolBackPressure
).toBe(1)
923 expect(poolInfo
).toStrictEqual({
925 type
: PoolTypes
.dynamic
,
926 worker
: WorkerTypes
.thread
,
927 ready
: expect
.any(Boolean
),
928 strategy
: WorkerChoiceStrategies
.ROUND_ROBIN
,
929 minSize
: expect
.any(Number
),
930 maxSize
: expect
.any(Number
),
931 workerNodes
: expect
.any(Number
),
932 idleWorkerNodes
: expect
.any(Number
),
933 busyWorkerNodes
: expect
.any(Number
),
934 executedTasks
: expect
.any(Number
),
935 executingTasks
: expect
.any(Number
),
936 failedTasks
: expect
.any(Number
)
941 it('Verify that listTaskFunctions() is working', async () => {
942 const dynamicThreadPool
= new DynamicThreadPool(
943 Math
.floor(numberOfWorkers
/ 2),
945 './tests/worker-files/thread/testMultipleTaskFunctionsWorker.js'
947 await
waitPoolEvents(dynamicThreadPool
, PoolEvents
.ready
, 1)
948 expect(dynamicThreadPool
.listTaskFunctions()).toStrictEqual([
950 'jsonIntegerSerialization',
954 const fixedClusterPool
= new FixedClusterPool(
956 './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.js'
958 await
waitPoolEvents(fixedClusterPool
, PoolEvents
.ready
, 1)
959 expect(fixedClusterPool
.listTaskFunctions()).toStrictEqual([
961 'jsonIntegerSerialization',
967 it('Verify that multiple task functions worker is working', async () => {
968 const pool
= new DynamicClusterPool(
969 Math
.floor(numberOfWorkers
/ 2),
971 './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.js'
973 const data
= { n
: 10 }
974 const result0
= await pool
.execute(data
)
975 expect(result0
).toStrictEqual({ ok
: 1 })
976 const result1
= await pool
.execute(data
, 'jsonIntegerSerialization')
977 expect(result1
).toStrictEqual({ ok
: 1 })
978 const result2
= await pool
.execute(data
, 'factorial')
979 expect(result2
).toBe(3628800)
980 const result3
= await pool
.execute(data
, 'fibonacci')
981 expect(result3
).toBe(55)
982 expect(pool
.info
.executingTasks
).toBe(0)
983 expect(pool
.info
.executedTasks
).toBe(4)
984 for (const workerNode
of pool
.workerNodes
) {
985 expect(workerNode
.info
.taskFunctions
).toStrictEqual([
987 'jsonIntegerSerialization',
991 expect(workerNode
.taskFunctionsUsage
.size
).toBe(3)
992 for (const name
of pool
.listTaskFunctions()) {
993 expect(workerNode
.getTaskFunctionWorkerUsage(name
)).toStrictEqual({
995 executed
: expect
.any(Number
),
996 executing
: expect
.any(Number
),
1001 history
: expect
.any(CircularArray
)
1004 history
: expect
.any(CircularArray
)
1008 history
: expect
.any(CircularArray
)
1011 history
: expect
.any(CircularArray
)
1016 workerNode
.getTaskFunctionWorkerUsage(name
).tasks
.executing
1017 ).toBeGreaterThanOrEqual(0)