Commit | Line | Data |
---|---|---|
bbeadd16 | 1 | import { DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS } from '../../utils' |
c4855468 | 2 | import type { IPool } from '../pool' |
f06e48d8 | 3 | import type { IWorker } from '../worker' |
51fe3d3c | 4 | import { FairShareWorkerChoiceStrategy } from './fair-share-worker-choice-strategy' |
feec6e8c | 5 | import { InterleavedWeightedRoundRobinWorkerChoiceStrategy } from './interleaved-weighted-round-robin-worker-choice-strategy' |
e4543b14 JB |
6 | import { LeastBusyWorkerChoiceStrategy } from './least-busy-worker-choice-strategy' |
7 | import { LeastUsedWorkerChoiceStrategy } from './least-used-worker-choice-strategy' | |
058a9457 | 8 | import { LeastEluWorkerChoiceStrategy } from './least-elu-worker-choice-strategy' |
51fe3d3c | 9 | import { RoundRobinWorkerChoiceStrategy } from './round-robin-worker-choice-strategy' |
bdaf31cd JB |
10 | import type { |
11 | IWorkerChoiceStrategy, | |
6c6afb84 | 12 | StrategyPolicy, |
87de9ff5 | 13 | TaskStatisticsRequirements, |
da309861 JB |
14 | WorkerChoiceStrategy, |
15 | WorkerChoiceStrategyOptions | |
bdaf31cd JB |
16 | } from './selection-strategies-types' |
17 | import { WorkerChoiceStrategies } from './selection-strategies-types' | |
51fe3d3c | 18 | import { 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 | */ |
27 | export 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 | */ | |
40 | private choiceRetriesCount = 0 | |
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 && | |
181 | this.choiceRetriesCount < (this.opts.choiceRetries as number) | |
182 | ) { | |
183 | this.choiceRetriesCount++ | |
184 | return this.execute() | |
185 | } else if (workerNodeKey == null) { | |
e695d66f | 186 | throw new Error( |
4ba8492f JB |
187 | `Worker node key chosen is null or undefined after ${this.choiceRetriesCount} retries` |
188 | ) | |
b0d6ed8f | 189 | } |
0ffa432e | 190 | this.choiceRetriesCount = 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 | } |