perf: remove unneeded class indirection for dynamic pool in worker
[poolifier.git] / tests / pools / selection-strategies / selection-strategies.test.js
1 const { expect } = require('expect')
2 const {
3 WorkerChoiceStrategies,
4 DynamicThreadPool,
5 FixedThreadPool,
6 FixedClusterPool
7 } = require('../../../lib/index')
8
9 describe('Selection strategies test suite', () => {
10 const min = 0
11 const max = 3
12
13 it('Verify that WorkerChoiceStrategies enumeration provides string values', () => {
14 expect(WorkerChoiceStrategies.ROUND_ROBIN).toBe('ROUND_ROBIN')
15 expect(WorkerChoiceStrategies.LESS_USED).toBe('LESS_USED')
16 expect(WorkerChoiceStrategies.LESS_BUSY).toBe('LESS_BUSY')
17 expect(WorkerChoiceStrategies.FAIR_SHARE).toBe('FAIR_SHARE')
18 expect(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN).toBe(
19 'WEIGHTED_ROUND_ROBIN'
20 )
21 })
22
23 it('Verify ROUND_ROBIN strategy is the default at pool creation', async () => {
24 const pool = new DynamicThreadPool(
25 min,
26 max,
27 './tests/worker-files/thread/testWorker.js'
28 )
29 expect(pool.opts.workerChoiceStrategy).toBe(
30 WorkerChoiceStrategies.ROUND_ROBIN
31 )
32 // We need to clean up the resources after our test
33 await pool.destroy()
34 })
35
36 it('Verify ROUND_ROBIN strategy is taken at pool creation', async () => {
37 const pool = new FixedThreadPool(
38 max,
39 './tests/worker-files/thread/testWorker.js',
40 { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN }
41 )
42 expect(pool.opts.workerChoiceStrategy).toBe(
43 WorkerChoiceStrategies.ROUND_ROBIN
44 )
45 expect(
46 pool.workerChoiceStrategyContext.workerChoiceStrategy.nextWorkerId
47 ).toBe(0)
48 // We need to clean up the resources after our test
49 await pool.destroy()
50 })
51
52 it('Verify ROUND_ROBIN strategy can be set after pool creation', async () => {
53 const pool = new DynamicThreadPool(
54 min,
55 max,
56 './tests/worker-files/thread/testWorker.js'
57 )
58 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN)
59 expect(pool.opts.workerChoiceStrategy).toBe(
60 WorkerChoiceStrategies.ROUND_ROBIN
61 )
62 // We need to clean up the resources after our test
63 await pool.destroy()
64 })
65
66 it('Verify ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
67 let pool = new FixedThreadPool(
68 max,
69 './tests/worker-files/thread/testWorker.js'
70 )
71 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN)
72 expect(
73 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
74 ).toBe(false)
75 expect(
76 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
77 ).toBe(false)
78 await pool.destroy()
79 pool = new DynamicThreadPool(
80 min,
81 max,
82 './tests/worker-files/thread/testWorker.js'
83 )
84 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN)
85 expect(
86 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
87 ).toBe(false)
88 expect(
89 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
90 ).toBe(false)
91 // We need to clean up the resources after our test
92 await pool.destroy()
93 })
94
95 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
96 const pool = new FixedThreadPool(
97 max,
98 './tests/worker-files/thread/testWorker.js',
99 { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN }
100 )
101 expect(pool.opts.workerChoiceStrategy).toBe(
102 WorkerChoiceStrategies.ROUND_ROBIN
103 )
104 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
105 const promises = []
106 for (let i = 0; i < max * 2; i++) {
107 promises.push(pool.execute())
108 }
109 await Promise.all(promises)
110 // We need to clean up the resources after our test
111 await pool.destroy()
112 })
113
114 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
115 const pool = new DynamicThreadPool(
116 min,
117 max,
118 './tests/worker-files/thread/testWorker.js',
119 { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN }
120 )
121 expect(pool.opts.workerChoiceStrategy).toBe(
122 WorkerChoiceStrategies.ROUND_ROBIN
123 )
124 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
125 const promises = []
126 for (let i = 0; i < max * 2; i++) {
127 promises.push(pool.execute())
128 }
129 await Promise.all(promises)
130 // We need to clean up the resources after our test
131 await pool.destroy()
132 })
133
134 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
135 let pool = new FixedClusterPool(
136 max,
137 './tests/worker-files/cluster/testWorker.js'
138 )
139 let results = new Set()
140 for (let i = 0; i < max; i++) {
141 results.add(pool.chooseWorker()[1].id)
142 }
143 expect(results.size).toBe(max)
144 await pool.destroy()
145 pool = new FixedThreadPool(max, './tests/worker-files/thread/testWorker.js')
146 results = new Set()
147 for (let i = 0; i < max; i++) {
148 results.add(pool.chooseWorker()[1].threadId)
149 }
150 expect(results.size).toBe(max)
151 await pool.destroy()
152 })
153
154 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
155 let pool = new FixedThreadPool(
156 max,
157 './tests/worker-files/thread/testWorker.js',
158 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
159 )
160 expect(
161 pool.workerChoiceStrategyContext.workerChoiceStrategy.nextWorkerId
162 ).toBeUndefined()
163 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN)
164 expect(
165 pool.workerChoiceStrategyContext.workerChoiceStrategy.nextWorkerId
166 ).toBe(0)
167 await pool.destroy()
168 pool = new DynamicThreadPool(
169 min,
170 max,
171 './tests/worker-files/thread/testWorker.js',
172 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
173 )
174 expect(
175 pool.workerChoiceStrategyContext.workerChoiceStrategy.nextWorkerId
176 ).toBeUndefined()
177 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN)
178 expect(
179 pool.workerChoiceStrategyContext.workerChoiceStrategy.nextWorkerId
180 ).toBe(0)
181 // We need to clean up the resources after our test
182 await pool.destroy()
183 })
184
185 it('Verify LESS_USED strategy is taken at pool creation', async () => {
186 const pool = new FixedThreadPool(
187 max,
188 './tests/worker-files/thread/testWorker.js',
189 { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED }
190 )
191 expect(pool.opts.workerChoiceStrategy).toBe(
192 WorkerChoiceStrategies.LESS_USED
193 )
194 // We need to clean up the resources after our test
195 await pool.destroy()
196 })
197
198 it('Verify LESS_USED strategy can be set after pool creation', async () => {
199 const pool = new FixedThreadPool(
200 max,
201 './tests/worker-files/thread/testWorker.js'
202 )
203 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_USED)
204 expect(pool.opts.workerChoiceStrategy).toBe(
205 WorkerChoiceStrategies.LESS_USED
206 )
207 // We need to clean up the resources after our test
208 await pool.destroy()
209 })
210
211 it('Verify LESS_USED strategy default tasks usage statistics requirements', async () => {
212 let pool = new FixedThreadPool(
213 max,
214 './tests/worker-files/thread/testWorker.js'
215 )
216 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_USED)
217 expect(
218 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
219 ).toBe(false)
220 expect(
221 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
222 ).toBe(false)
223 await pool.destroy()
224 pool = new DynamicThreadPool(
225 min,
226 max,
227 './tests/worker-files/thread/testWorker.js'
228 )
229 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_USED)
230 expect(
231 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
232 ).toBe(false)
233 expect(
234 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
235 ).toBe(false)
236 // We need to clean up the resources after our test
237 await pool.destroy()
238 })
239
240 it('Verify LESS_USED strategy can be run in a fixed pool', async () => {
241 const pool = new FixedThreadPool(
242 max,
243 './tests/worker-files/thread/testWorker.js',
244 { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED }
245 )
246 // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose`
247 const promises = []
248 for (let i = 0; i < max * 2; i++) {
249 promises.push(pool.execute())
250 }
251 await Promise.all(promises)
252 // We need to clean up the resources after our test
253 await pool.destroy()
254 })
255
256 it('Verify LESS_USED strategy can be run in a dynamic pool', async () => {
257 const pool = new DynamicThreadPool(
258 min,
259 max,
260 './tests/worker-files/thread/testWorker.js',
261 { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED }
262 )
263 // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose`
264 const promises = []
265 for (let i = 0; i < max * 2; i++) {
266 promises.push(pool.execute())
267 }
268 await Promise.all(promises)
269 // We need to clean up the resources after our test
270 await pool.destroy()
271 })
272
273 it('Verify LESS_BUSY strategy is taken at pool creation', async () => {
274 const pool = new FixedThreadPool(
275 max,
276 './tests/worker-files/thread/testWorker.js',
277 { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY }
278 )
279 expect(pool.opts.workerChoiceStrategy).toBe(
280 WorkerChoiceStrategies.LESS_BUSY
281 )
282 // We need to clean up the resources after our test
283 await pool.destroy()
284 })
285
286 it('Verify LESS_BUSY strategy can be set after pool creation', async () => {
287 const pool = new FixedThreadPool(
288 max,
289 './tests/worker-files/thread/testWorker.js'
290 )
291 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_BUSY)
292 expect(pool.opts.workerChoiceStrategy).toBe(
293 WorkerChoiceStrategies.LESS_BUSY
294 )
295 // We need to clean up the resources after our test
296 await pool.destroy()
297 })
298
299 it('Verify LESS_BUSY strategy default tasks usage statistics requirements', async () => {
300 let pool = new FixedThreadPool(
301 max,
302 './tests/worker-files/thread/testWorker.js'
303 )
304 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_BUSY)
305 expect(
306 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
307 ).toBe(true)
308 expect(
309 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
310 ).toBe(false)
311 await pool.destroy()
312 pool = new DynamicThreadPool(
313 min,
314 max,
315 './tests/worker-files/thread/testWorker.js'
316 )
317 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_BUSY)
318 expect(
319 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
320 ).toBe(true)
321 expect(
322 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
323 ).toBe(false)
324 // We need to clean up the resources after our test
325 await pool.destroy()
326 })
327
328 it('Verify LESS_BUSY strategy can be run in a fixed pool', async () => {
329 const pool = new FixedThreadPool(
330 max,
331 './tests/worker-files/thread/testWorker.js',
332 { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY }
333 )
334 // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose`
335 const promises = []
336 for (let i = 0; i < max * 2; i++) {
337 promises.push(pool.execute())
338 }
339 await Promise.all(promises)
340 // We need to clean up the resources after our test
341 await pool.destroy()
342 })
343
344 it('Verify LESS_BUSY strategy can be run in a dynamic pool', async () => {
345 const pool = new DynamicThreadPool(
346 min,
347 max,
348 './tests/worker-files/thread/testWorker.js',
349 { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY }
350 )
351 // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose`
352 const promises = []
353 for (let i = 0; i < max * 2; i++) {
354 promises.push(pool.execute())
355 }
356 await Promise.all(promises)
357 // We need to clean up the resources after our test
358 await pool.destroy()
359 })
360
361 it('Verify FAIR_SHARE strategy is taken at pool creation', async () => {
362 const pool = new FixedThreadPool(
363 max,
364 './tests/worker-files/thread/testWorker.js',
365 { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE }
366 )
367 expect(pool.opts.workerChoiceStrategy).toBe(
368 WorkerChoiceStrategies.FAIR_SHARE
369 )
370 for (const workerKey of pool.workerChoiceStrategyContext.workerChoiceStrategy.workerLastVirtualTaskTimestamp.keys()) {
371 expect(
372 pool.workerChoiceStrategyContext.workerChoiceStrategy.workerLastVirtualTaskTimestamp.get(
373 workerKey
374 ).start
375 ).toBe(0)
376 expect(
377 pool.workerChoiceStrategyContext.workerChoiceStrategy.workerLastVirtualTaskTimestamp.get(
378 workerKey
379 ).end
380 ).toBe(0)
381 }
382 // We need to clean up the resources after our test
383 await pool.destroy()
384 })
385
386 it('Verify FAIR_SHARE strategy can be set after pool creation', async () => {
387 const pool = new FixedThreadPool(
388 max,
389 './tests/worker-files/thread/testWorker.js'
390 )
391 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE)
392 expect(pool.opts.workerChoiceStrategy).toBe(
393 WorkerChoiceStrategies.FAIR_SHARE
394 )
395 // We need to clean up the resources after our test
396 await pool.destroy()
397 })
398
399 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
400 let pool = new FixedThreadPool(
401 max,
402 './tests/worker-files/thread/testWorker.js'
403 )
404 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE)
405 expect(
406 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
407 ).toBe(true)
408 expect(
409 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
410 ).toBe(true)
411 await pool.destroy()
412 pool = new DynamicThreadPool(
413 min,
414 max,
415 './tests/worker-files/thread/testWorker.js'
416 )
417 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE)
418 expect(
419 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
420 ).toBe(true)
421 expect(
422 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
423 ).toBe(true)
424 // We need to clean up the resources after our test
425 await pool.destroy()
426 })
427
428 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
429 const pool = new FixedThreadPool(
430 max,
431 './tests/worker-files/thread/testWorker.js',
432 { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE }
433 )
434 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
435 const promises = []
436 for (let i = 0; i < max * 2; i++) {
437 promises.push(pool.execute())
438 }
439 await Promise.all(promises)
440 expect(
441 pool.workerChoiceStrategyContext.workerChoiceStrategy
442 .workerLastVirtualTaskTimestamp.size
443 ).toBe(pool.workers.length)
444 // We need to clean up the resources after our test
445 await pool.destroy()
446 })
447
448 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
449 const pool = new DynamicThreadPool(
450 min,
451 max,
452 './tests/worker-files/thread/testWorker.js',
453 { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE }
454 )
455 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
456 const promises = []
457 const maxMultiplier = 2
458 for (let i = 0; i < max * maxMultiplier; i++) {
459 promises.push(pool.execute())
460 }
461 await Promise.all(promises)
462 // if (process.platform !== 'win32') {
463 // expect(
464 // pool.workerChoiceStrategyContext.workerChoiceStrategy
465 // .workerLastVirtualTaskTimestamp.size
466 // ).toBe(pool.workers.length)
467 // }
468 // We need to clean up the resources after our test
469 await pool.destroy()
470 })
471
472 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
473 let pool = new FixedThreadPool(
474 max,
475 './tests/worker-files/thread/testWorker.js'
476 )
477 expect(
478 pool.workerChoiceStrategyContext.workerChoiceStrategy
479 .workerLastVirtualTaskTimestamp
480 ).toBeUndefined()
481 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE)
482 for (const workerKey of pool.workerChoiceStrategyContext.workerChoiceStrategy.workerLastVirtualTaskTimestamp.keys()) {
483 expect(
484 pool.workerChoiceStrategyContext.workerChoiceStrategy.workerLastVirtualTaskTimestamp.get(
485 workerKey
486 ).start
487 ).toBe(0)
488 expect(
489 pool.workerChoiceStrategyContext.workerChoiceStrategy.workerLastVirtualTaskTimestamp.get(
490 workerKey
491 ).end
492 ).toBe(0)
493 }
494 await pool.destroy()
495 pool = new DynamicThreadPool(
496 min,
497 max,
498 './tests/worker-files/thread/testWorker.js'
499 )
500 expect(
501 pool.workerChoiceStrategyContext.workerChoiceStrategy
502 .workerLastVirtualTaskTimestamp
503 ).toBeUndefined()
504 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE)
505 for (const workerKey of pool.workerChoiceStrategyContext.workerChoiceStrategy.workerLastVirtualTaskTimestamp.keys()) {
506 expect(
507 pool.workerChoiceStrategyContext.workerChoiceStrategy.workerLastVirtualTaskTimestamp.get(
508 workerKey
509 ).start
510 ).toBe(0)
511 expect(
512 pool.workerChoiceStrategyContext.workerChoiceStrategy.workerLastVirtualTaskTimestamp.get(
513 workerKey
514 ).end
515 ).toBe(0)
516 }
517 // We need to clean up the resources after our test
518 await pool.destroy()
519 })
520
521 it('Verify WEIGHTED_ROUND_ROBIN strategy is taken at pool creation', async () => {
522 const pool = new FixedThreadPool(
523 max,
524 './tests/worker-files/thread/testWorker.js',
525 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
526 )
527 expect(pool.opts.workerChoiceStrategy).toBe(
528 WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
529 )
530 expect(
531 pool.workerChoiceStrategyContext.workerChoiceStrategy.currentWorkerId
532 ).toBe(0)
533 expect(
534 pool.workerChoiceStrategyContext.workerChoiceStrategy.defaultWorkerWeight
535 ).toBeGreaterThan(0)
536 for (const workerKey of pool.workerChoiceStrategyContext.workerChoiceStrategy.workersTaskRunTime.keys()) {
537 expect(
538 pool.workerChoiceStrategyContext.workerChoiceStrategy.workersTaskRunTime.get(
539 workerKey
540 ).weight
541 ).toBeGreaterThan(0)
542 expect(
543 pool.workerChoiceStrategyContext.workerChoiceStrategy.workersTaskRunTime.get(
544 workerKey
545 ).runTime
546 ).toBe(0)
547 }
548 // We need to clean up the resources after our test
549 await pool.destroy()
550 })
551
552 it('Verify WEIGHTED_ROUND_ROBIN strategy can be set after pool creation', async () => {
553 const pool = new FixedThreadPool(
554 max,
555 './tests/worker-files/thread/testWorker.js'
556 )
557 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN)
558 expect(pool.opts.workerChoiceStrategy).toBe(
559 WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
560 )
561 // We need to clean up the resources after our test
562 await pool.destroy()
563 })
564
565 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
566 let pool = new FixedThreadPool(
567 max,
568 './tests/worker-files/thread/testWorker.js'
569 )
570 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN)
571 expect(
572 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
573 ).toBe(true)
574 expect(
575 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
576 ).toBe(true)
577 await pool.destroy()
578 pool = new DynamicThreadPool(
579 min,
580 max,
581 './tests/worker-files/thread/testWorker.js'
582 )
583 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN)
584 expect(
585 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
586 ).toBe(true)
587 expect(
588 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
589 ).toBe(true)
590 // We need to clean up the resources after our test
591 await pool.destroy()
592 })
593
594 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
595 const pool = new FixedThreadPool(
596 max,
597 './tests/worker-files/thread/testWorker.js',
598 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
599 )
600 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
601 const promises = []
602 for (let i = 0; i < max * 2; i++) {
603 promises.push(pool.execute())
604 }
605 await Promise.all(promises)
606 expect(
607 pool.workerChoiceStrategyContext.workerChoiceStrategy.workersTaskRunTime
608 .size
609 ).toBe(pool.workers.length)
610 // We need to clean up the resources after our test
611 await pool.destroy()
612 })
613
614 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
615 const pool = new DynamicThreadPool(
616 min,
617 max,
618 './tests/worker-files/thread/testWorker.js',
619 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
620 )
621 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
622 const promises = []
623 const maxMultiplier =
624 pool.workerChoiceStrategyContext.workerChoiceStrategy
625 .defaultWorkerWeight * 2
626 for (let i = 0; i < max * maxMultiplier; i++) {
627 promises.push(pool.execute())
628 }
629 await Promise.all(promises)
630 if (process.platform !== 'win32') {
631 expect(
632 pool.workerChoiceStrategyContext.workerChoiceStrategy.workersTaskRunTime
633 .size
634 ).toBe(pool.workers.length)
635 }
636 // We need to clean up the resources after our test
637 await pool.destroy()
638 })
639
640 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
641 let pool = new FixedThreadPool(
642 max,
643 './tests/worker-files/thread/testWorker.js'
644 )
645 expect(
646 pool.workerChoiceStrategyContext.workerChoiceStrategy.currentWorkerId
647 ).toBeUndefined()
648 expect(
649 pool.workerChoiceStrategyContext.workerChoiceStrategy.defaultWorkerWeight
650 ).toBeUndefined()
651 expect(
652 pool.workerChoiceStrategyContext.workerChoiceStrategy.workersTaskRunTime
653 ).toBeUndefined()
654 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN)
655 expect(
656 pool.workerChoiceStrategyContext.workerChoiceStrategy.currentWorkerId
657 ).toBe(0)
658 expect(
659 pool.workerChoiceStrategyContext.workerChoiceStrategy.defaultWorkerWeight
660 ).toBeGreaterThan(0)
661 for (const workerKey of pool.workerChoiceStrategyContext.workerChoiceStrategy.workersTaskRunTime.keys()) {
662 expect(
663 pool.workerChoiceStrategyContext.workerChoiceStrategy.workersTaskRunTime.get(
664 workerKey
665 ).runTime
666 ).toBe(0)
667 }
668 await pool.destroy()
669 pool = new DynamicThreadPool(
670 min,
671 max,
672 './tests/worker-files/thread/testWorker.js'
673 )
674 expect(
675 pool.workerChoiceStrategyContext.workerChoiceStrategy.currentWorkerId
676 ).toBeUndefined()
677 expect(
678 pool.workerChoiceStrategyContext.workerChoiceStrategy.defaultWorkerWeight
679 ).toBeUndefined()
680 expect(
681 pool.workerChoiceStrategyContext.workerChoiceStrategy.workersTaskRunTime
682 ).toBeUndefined()
683 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN)
684 expect(
685 pool.workerChoiceStrategyContext.workerChoiceStrategy.currentWorkerId
686 ).toBe(0)
687 expect(
688 pool.workerChoiceStrategyContext.workerChoiceStrategy.defaultWorkerWeight
689 ).toBeGreaterThan(0)
690 for (const workerKey of pool.workerChoiceStrategyContext.workerChoiceStrategy.workersTaskRunTime.keys()) {
691 expect(
692 pool.workerChoiceStrategyContext.workerChoiceStrategy.workersTaskRunTime.get(
693 workerKey
694 ).runTime
695 ).toBe(0)
696 }
697 // We need to clean up the resources after our test
698 await pool.destroy()
699 })
700
701 it('Verify unknown strategies throw error', () => {
702 expect(
703 () =>
704 new DynamicThreadPool(
705 min,
706 max,
707 './tests/worker-files/thread/testWorker.js',
708 { workerChoiceStrategy: 'UNKNOWN_STRATEGY' }
709 )
710 ).toThrowError(
711 new Error("Worker choice strategy 'UNKNOWN_STRATEGY' not found")
712 )
713 })
714 })