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