refactor: cleanup worker choice strategies options namespace
[poolifier.git] / src / pools / selection-strategies / worker-choice-strategy-context.ts
CommitLineData
bbeadd16 1import { DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS } from '../../utils'
c4855468 2import type { IPool } from '../pool'
f06e48d8 3import type { IWorker } from '../worker'
51fe3d3c 4import { FairShareWorkerChoiceStrategy } from './fair-share-worker-choice-strategy'
feec6e8c 5import { InterleavedWeightedRoundRobinWorkerChoiceStrategy } from './interleaved-weighted-round-robin-worker-choice-strategy'
e4543b14
JB
6import { LeastBusyWorkerChoiceStrategy } from './least-busy-worker-choice-strategy'
7import { LeastUsedWorkerChoiceStrategy } from './least-used-worker-choice-strategy'
058a9457 8import { LeastEluWorkerChoiceStrategy } from './least-elu-worker-choice-strategy'
51fe3d3c 9import { RoundRobinWorkerChoiceStrategy } from './round-robin-worker-choice-strategy'
bdaf31cd
JB
10import type {
11 IWorkerChoiceStrategy,
6c6afb84 12 StrategyPolicy,
87de9ff5 13 TaskStatisticsRequirements,
da309861
JB
14 WorkerChoiceStrategy,
15 WorkerChoiceStrategyOptions
bdaf31cd
JB
16} from './selection-strategies-types'
17import { WorkerChoiceStrategies } from './selection-strategies-types'
51fe3d3c 18import { WeightedRoundRobinWorkerChoiceStrategy } from './weighted-round-robin-worker-choice-strategy'
bdaf31cd
JB
19
20/**
21 * The worker choice strategy context.
22 *
38e795c1 23 * @typeParam Worker - Type of worker.
e102732c
JB
24 * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
25 * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
bdaf31cd
JB
26 */
27export class WorkerChoiceStrategyContext<
f06e48d8 28 Worker extends IWorker,
b2b1d84e
JB
29 Data = unknown,
30 Response = unknown
bdaf31cd 31> {
b529c323 32 private readonly workerChoiceStrategies: Map<
95c83464 33 WorkerChoiceStrategy,
17393ac8 34 IWorkerChoiceStrategy
b529c323 35 >
bdaf31cd 36
8990357d
JB
37 /**
38 * The number of times the worker choice strategy in the context has been retried.
39 */
8c0b113f 40 private retriesCount = 0
8990357d 41
bdaf31cd
JB
42 /**
43 * Worker choice strategy context constructor.
44 *
38e795c1 45 * @param pool - The pool instance.
d710242d 46 * @param workerChoiceStrategy - The worker choice strategy.
da309861 47 * @param opts - The worker choice strategy options.
bdaf31cd
JB
48 */
49 public constructor (
c4855468 50 pool: IPool<Worker, Data, Response>,
d710242d 51 private workerChoiceStrategy: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN,
8990357d 52 private opts: WorkerChoiceStrategyOptions = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS
bdaf31cd 53 ) {
8990357d 54 this.opts = { ...DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS, ...opts }
7254e419 55 this.execute = this.execute.bind(this)
b529c323
JB
56 this.workerChoiceStrategies = new Map<
57 WorkerChoiceStrategy,
17393ac8 58 IWorkerChoiceStrategy
b529c323
JB
59 >([
60 [
61 WorkerChoiceStrategies.ROUND_ROBIN,
7254e419
JB
62 new (RoundRobinWorkerChoiceStrategy.bind(this))<Worker, Data, Response>(
63 pool,
64 opts
65 )
b529c323
JB
66 ],
67 [
e4543b14
JB
68 WorkerChoiceStrategies.LEAST_USED,
69 new (LeastUsedWorkerChoiceStrategy.bind(this))<Worker, Data, Response>(
7254e419
JB
70 pool,
71 opts
72 )
b529c323
JB
73 ],
74 [
e4543b14
JB
75 WorkerChoiceStrategies.LEAST_BUSY,
76 new (LeastBusyWorkerChoiceStrategy.bind(this))<Worker, Data, Response>(
7254e419
JB
77 pool,
78 opts
79 )
b529c323
JB
80 ],
81 [
058a9457
JB
82 WorkerChoiceStrategies.LEAST_ELU,
83 new (LeastEluWorkerChoiceStrategy.bind(this))<Worker, Data, Response>(
84 pool,
85 opts
86 )
87 ],
88 [
b529c323 89 WorkerChoiceStrategies.FAIR_SHARE,
7254e419 90 new (FairShareWorkerChoiceStrategy.bind(this))<Worker, Data, Response>(
da309861
JB
91 pool,
92 opts
93 )
7254e419
JB
94 ],
95 [
96 WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN,
97 new (WeightedRoundRobinWorkerChoiceStrategy.bind(this))<
98 Worker,
99 Data,
100 Response
101 >(pool, opts)
feec6e8c
JB
102 ],
103 [
104 WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN,
105 new (InterleavedWeightedRoundRobinWorkerChoiceStrategy.bind(this))<
106 Worker,
107 Data,
108 Response
109 >(pool, opts)
b529c323
JB
110 ]
111 ])
bdaf31cd
JB
112 }
113
6c6afb84
JB
114 /**
115 * Gets the strategy policy in the context.
116 *
117 * @returns The strategy policy.
118 */
119 public getStrategyPolicy (): StrategyPolicy {
120 return (
121 this.workerChoiceStrategies.get(
122 this.workerChoiceStrategy
123 ) as IWorkerChoiceStrategy
124 ).strategyPolicy
125 }
126
97a2abc3 127 /**
8990357d 128 * Gets the worker choice strategy in the context task statistics requirements.
97a2abc3 129 *
87de9ff5 130 * @returns The task statistics requirements.
97a2abc3 131 */
87de9ff5 132 public getTaskStatisticsRequirements (): TaskStatisticsRequirements {
95c83464
JB
133 return (
134 this.workerChoiceStrategies.get(
d710242d 135 this.workerChoiceStrategy
17393ac8 136 ) as IWorkerChoiceStrategy
87de9ff5 137 ).taskStatisticsRequirements
97a2abc3
JB
138 }
139
bdaf31cd 140 /**
bdede008 141 * Sets the worker choice strategy to use in the context.
bdaf31cd 142 *
38e795c1 143 * @param workerChoiceStrategy - The worker choice strategy to set.
bdaf31cd
JB
144 */
145 public setWorkerChoiceStrategy (
146 workerChoiceStrategy: WorkerChoiceStrategy
147 ): void {
d710242d
JB
148 if (this.workerChoiceStrategy !== workerChoiceStrategy) {
149 this.workerChoiceStrategy = workerChoiceStrategy
b2b1d84e 150 }
d710242d 151 this.workerChoiceStrategies.get(this.workerChoiceStrategy)?.reset()
bdaf31cd
JB
152 }
153
138d29a8 154 /**
8990357d 155 * Updates the worker node key in the worker choice strategy in the context internals.
138d29a8
JB
156 *
157 * @returns `true` if the update is successful, `false` otherwise.
158 */
a4958de2 159 public update (workerNodeKey: number): boolean {
138d29a8
JB
160 return (
161 this.workerChoiceStrategies.get(
162 this.workerChoiceStrategy
163 ) as IWorkerChoiceStrategy
a4958de2 164 ).update(workerNodeKey)
138d29a8
JB
165 }
166
bdaf31cd 167 /**
8990357d 168 * Executes the worker choice strategy in the context algorithm.
bdaf31cd 169 *
f06e48d8 170 * @returns The key of the worker node.
336e91c4 171 * @throws {@link https://nodejs.org/api/errors.html#class-error} If after configured retries the worker node key is null or undefined .
bdaf31cd 172 */
c923ce56 173 public execute (): number {
b0d6ed8f 174 const workerNodeKey = (
17393ac8 175 this.workerChoiceStrategies.get(
d710242d 176 this.workerChoiceStrategy
17393ac8
JB
177 ) as IWorkerChoiceStrategy
178 ).choose()
8990357d
JB
179 if (
180 workerNodeKey == null &&
8c0b113f 181 this.retriesCount < (this.opts.retries as number)
8990357d 182 ) {
8c0b113f 183 this.retriesCount++
8990357d
JB
184 return this.execute()
185 } else if (workerNodeKey == null) {
e695d66f 186 throw new Error(
8c0b113f 187 `Worker node key chosen is null or undefined after ${this.retriesCount} retries`
4ba8492f 188 )
b0d6ed8f 189 }
8c0b113f 190 this.retriesCount = 0
b0d6ed8f 191 return workerNodeKey
bdaf31cd 192 }
97a2abc3
JB
193
194 /**
c7e196ba 195 * Removes the worker node key from the worker choice strategy in the context.
97a2abc3 196 *
501aea93 197 * @param workerNodeKey - The worker node key.
97a2abc3
JB
198 * @returns `true` if the removal is successful, `false` otherwise.
199 */
f06e48d8 200 public remove (workerNodeKey: number): boolean {
95c83464
JB
201 return (
202 this.workerChoiceStrategies.get(
d710242d 203 this.workerChoiceStrategy
17393ac8 204 ) as IWorkerChoiceStrategy
f06e48d8 205 ).remove(workerNodeKey)
95c83464 206 }
a20f0ba5
JB
207
208 /**
209 * Sets the worker choice strategies in the context options.
210 *
211 * @param opts - The worker choice strategy options.
212 */
213 public setOptions (opts: WorkerChoiceStrategyOptions): void {
8990357d 214 this.opts = { ...DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS, ...opts }
0509fd43 215 for (const workerChoiceStrategy of this.workerChoiceStrategies.values()) {
a20f0ba5 216 workerChoiceStrategy.setOptions(opts)
0509fd43 217 }
a20f0ba5 218 }
bdaf31cd 219}