f98ec5ef09e78eafe2b033eb54f13460a5917241
[poolifier.git] / src / pools / selection-strategies / dynamic-pool-worker-choice-strategy.ts
1 import type { AbstractPoolWorker } from '../abstract-pool-worker'
2 import type { IPoolInternal } from '../pool-internal'
3 import { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy'
4 import type {
5 IWorkerChoiceStrategy,
6 WorkerChoiceStrategy
7 } from './selection-strategies-types'
8 import { WorkerChoiceStrategies } from './selection-strategies-types'
9 import { SelectionStrategiesUtils } from './selection-strategies-utils'
10
11 /**
12 * Dynamically choose a worker.
13 *
14 * @template Worker Type of worker which manages the strategy.
15 * @template Data Type of data sent to the worker. This can only be serializable data.
16 * @template Response Type of response of execution. This can only be serializable data.
17 */
18 export class DynamicPoolWorkerChoiceStrategy<
19 Worker extends AbstractPoolWorker,
20 Data,
21 Response
22 > extends AbstractWorkerChoiceStrategy<Worker, Data, Response> {
23 private workerChoiceStrategy: IWorkerChoiceStrategy<Worker>
24
25 /**
26 * Constructs a worker choice strategy for dynamical pool.
27 *
28 * @param pool The pool instance.
29 * @param createDynamicallyWorkerCallback The worker creation callback for dynamic pool.
30 * @param workerChoiceStrategy The worker choice strategy when the pull is busy.
31 */
32 public constructor (
33 pool: IPoolInternal<Worker, Data, Response>,
34 private createDynamicallyWorkerCallback: () => Worker,
35 workerChoiceStrategy: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
36 ) {
37 super(pool)
38 this.workerChoiceStrategy = SelectionStrategiesUtils.getWorkerChoiceStrategy(
39 this.pool,
40 workerChoiceStrategy
41 )
42 }
43
44 /** @inheritdoc */
45 public choose (): Worker {
46 const freeWorker = this.pool.findFreeWorker()
47 if (freeWorker) {
48 return freeWorker
49 }
50
51 if (this.pool.busy) {
52 return this.workerChoiceStrategy.choose()
53 }
54
55 // All workers are busy, create a new worker
56 return this.createDynamicallyWorkerCallback()
57 }
58 }