1 import type { IPoolInternal
} from
'../pool-internal'
2 import type { IPoolWorker
} from
'../pool-worker'
3 import { FairShareWorkerChoiceStrategy
} from
'./fair-share-worker-choice-strategy'
4 import { LessBusyWorkerChoiceStrategy
} from
'./less-busy-worker-choice-strategy'
5 import { LessUsedWorkerChoiceStrategy
} from
'./less-used-worker-choice-strategy'
6 import { RoundRobinWorkerChoiceStrategy
} from
'./round-robin-worker-choice-strategy'
11 } from
'./selection-strategies-types'
12 import { WorkerChoiceStrategies
} from
'./selection-strategies-types'
13 import { WeightedRoundRobinWorkerChoiceStrategy
} from
'./weighted-round-robin-worker-choice-strategy'
16 * The worker choice strategy context.
18 * @typeParam Worker - Type of worker.
19 * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
20 * @typeParam Response - Type of response of execution. This can only be serializable data.
22 export class WorkerChoiceStrategyContext
<
23 Worker
extends IPoolWorker
,
27 private readonly workerChoiceStrategies
= new Map
<
29 IWorkerChoiceStrategy
<Worker
, Data
, Response
>
33 * Worker choice strategy context constructor.
35 * @param pool - The pool instance.
36 * @param createWorkerCallback - The worker creation callback for dynamic pool.
37 * @param workerChoiceStrategy - The worker choice strategy.
40 pool
: IPoolInternal
<Worker
, Data
, Response
>,
41 private readonly createWorkerCallback
: () => number,
42 private workerChoiceStrategyType
: WorkerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
44 this.execute
.bind(this)
45 this.registerWorkerChoiceStrategy(pool
, workerChoiceStrategyType
)
49 * Gets the worker choice strategy in the context required statistics.
51 * @returns The required statistics.
53 public getRequiredStatistics (): RequiredStatistics
{
55 this.workerChoiceStrategies
.get(
56 this.workerChoiceStrategyType
57 ) as IWorkerChoiceStrategy
<Worker
, Data
, Response
>
62 * Sets the worker choice strategy to use in the context.
64 * @param workerChoiceStrategy - The worker choice strategy to set.
66 public setWorkerChoiceStrategy (
67 pool
: IPoolInternal
<Worker
, Data
, Response
>,
68 workerChoiceStrategy
: WorkerChoiceStrategy
70 if (this.workerChoiceStrategyType
=== workerChoiceStrategy
) {
71 this.workerChoiceStrategies
.get(workerChoiceStrategy
)?.reset()
73 this.workerChoiceStrategyType
= workerChoiceStrategy
74 this.registerWorkerChoiceStrategy(pool
, workerChoiceStrategy
)
79 * Executes the worker choice strategy algorithm in the context.
81 * @returns The key of the chosen one.
83 public execute (): number {
84 const workerChoiceStrategy
= this.workerChoiceStrategies
.get(
85 this.workerChoiceStrategyType
86 ) as IWorkerChoiceStrategy
<Worker
, Data
, Response
>
88 workerChoiceStrategy
.isDynamicPool
&&
89 !workerChoiceStrategy
.pool
.full
&&
90 workerChoiceStrategy
.pool
.findFreeWorkerKey() === -1
92 return this.createWorkerCallback()
94 return workerChoiceStrategy
.choose()
98 * Removes a worker from the worker choice strategy in the context.
100 * @param workerKey - The key of the worker to remove.
101 * @returns `true` if the removal is successful, `false` otherwise.
103 public remove (workerKey
: number): boolean {
105 this.workerChoiceStrategies
.get(
106 this.workerChoiceStrategyType
107 ) as IWorkerChoiceStrategy
<Worker
, Data
, Response
>
111 private registerWorkerChoiceStrategy (
112 pool
: IPoolInternal
<Worker
, Data
, Response
>,
113 workerChoiceStrategy
: WorkerChoiceStrategy
115 if (!this.workerChoiceStrategies
.has(workerChoiceStrategy
)) {
116 this.workerChoiceStrategies
.set(
117 workerChoiceStrategy
,
118 this.getWorkerChoiceStrategy(pool
, workerChoiceStrategy
)
124 * Gets the worker choice strategy instance.
126 * @param pool - The pool instance.
127 * @param workerChoiceStrategy - The worker choice strategy.
128 * @returns The worker choice strategy instance.
130 private getWorkerChoiceStrategy (
131 pool
: IPoolInternal
<Worker
, Data
, Response
>,
132 workerChoiceStrategy
: WorkerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
133 ): IWorkerChoiceStrategy
<Worker
, Data
, Response
> {
134 switch (workerChoiceStrategy
) {
135 case WorkerChoiceStrategies
.ROUND_ROBIN
:
136 return new RoundRobinWorkerChoiceStrategy
<Worker
, Data
, Response
>(pool
)
137 case WorkerChoiceStrategies
.LESS_USED
:
138 return new LessUsedWorkerChoiceStrategy
<Worker
, Data
, Response
>(pool
)
139 case WorkerChoiceStrategies
.LESS_BUSY
:
140 return new LessBusyWorkerChoiceStrategy
<Worker
, Data
, Response
>(pool
)
141 case WorkerChoiceStrategies
.FAIR_SHARE
:
142 return new FairShareWorkerChoiceStrategy
<Worker
, Data
, Response
>(pool
)
143 case WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
:
144 return new WeightedRoundRobinWorkerChoiceStrategy
<
151 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
152 `Worker choice strategy '${workerChoiceStrategy}' not found`