1 import type { IPool
} from
'../pool.js'
2 import type { IWorker
} from
'../worker.js'
6 TaskStatisticsRequirements
,
8 WorkerChoiceStrategyOptions
,
9 } from
'./selection-strategies-types.js'
10 import { WorkerChoiceStrategies
} from
'./selection-strategies-types.js'
12 buildWorkerChoiceStrategiesPolicy
,
13 buildWorkerChoiceStrategiesTaskStatisticsRequirements
,
14 getWorkerChoiceStrategiesRetries
,
15 getWorkerChoiceStrategy
,
16 } from
'./selection-strategies-utils.js'
19 * The worker choice strategies context.
20 * @typeParam Worker - Type of worker.
21 * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
22 * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
24 export class WorkerChoiceStrategiesContext
<
25 Worker
extends IWorker
,
30 * The number of worker choice strategies execution retries.
32 public retriesCount
: number
35 * The default worker choice strategy in the context.
37 private defaultWorkerChoiceStrategy
: WorkerChoiceStrategy
40 * The worker choice strategies registered in the context.
42 private readonly workerChoiceStrategies
: Map
<
48 * The active worker choice strategies in the context policy.
50 private workerChoiceStrategiesPolicy
: StrategyPolicy
53 * The active worker choice strategies in the context task statistics requirements.
55 private workerChoiceStrategiesTaskStatisticsRequirements
: TaskStatisticsRequirements
58 * The maximum number of worker choice strategies execution retries.
60 private readonly retries
: number
63 * Worker choice strategies context constructor.
64 * @param pool - The pool instance.
65 * @param workerChoiceStrategies - The worker choice strategies. @defaultValue [WorkerChoiceStrategies.ROUND_ROBIN]
66 * @param opts - The worker choice strategy options.
69 private readonly pool
: IPool
<Worker
, Data
, Response
>,
70 workerChoiceStrategies
: WorkerChoiceStrategy
[] = [
71 WorkerChoiceStrategies
.ROUND_ROBIN
,
73 opts
?: WorkerChoiceStrategyOptions
75 this.execute
= this.execute
.bind(this)
76 this.defaultWorkerChoiceStrategy
= workerChoiceStrategies
[0]
77 this.workerChoiceStrategies
= new Map
<
81 for (const workerChoiceStrategy
of workerChoiceStrategies
) {
82 this.addWorkerChoiceStrategy(workerChoiceStrategy
, this.pool
, opts
)
84 this.workerChoiceStrategiesPolicy
= buildWorkerChoiceStrategiesPolicy(
85 this.workerChoiceStrategies
87 this.workerChoiceStrategiesTaskStatisticsRequirements
=
88 buildWorkerChoiceStrategiesTaskStatisticsRequirements(
89 this.workerChoiceStrategies
92 this.retries
= getWorkerChoiceStrategiesRetries
<Worker
, Data
, Response
>(
99 * Gets the active worker choice strategies in the context policy.
100 * @returns The strategies policy.
102 public getPolicy (): StrategyPolicy
{
103 return this.workerChoiceStrategiesPolicy
107 * Gets the active worker choice strategies in the context task statistics requirements.
108 * @returns The strategies task statistics requirements.
110 public getTaskStatisticsRequirements (): TaskStatisticsRequirements
{
111 return this.workerChoiceStrategiesTaskStatisticsRequirements
115 * Sets the default worker choice strategy to use in the context.
116 * @param workerChoiceStrategy - The default worker choice strategy to set.
117 * @param opts - The worker choice strategy options.
119 public setDefaultWorkerChoiceStrategy (
120 workerChoiceStrategy
: WorkerChoiceStrategy
,
121 opts
?: WorkerChoiceStrategyOptions
123 if (workerChoiceStrategy
!== this.defaultWorkerChoiceStrategy
) {
124 this.defaultWorkerChoiceStrategy
= workerChoiceStrategy
125 this.addWorkerChoiceStrategy(workerChoiceStrategy
, this.pool
, opts
)
130 * Updates the worker node key in the active worker choice strategies in the context internals.
131 * @param workerNodeKey - The worker node key.
132 * @returns `true` if the update is successful, `false` otherwise.
134 public update (workerNodeKey
: number): boolean {
136 this.workerChoiceStrategies
,
137 ([_
, workerChoiceStrategy
]) => workerChoiceStrategy
.update(workerNodeKey
)
142 * Executes the given worker choice strategy in the context algorithm.
143 * @param workerChoiceStrategy - The worker choice strategy algorithm to execute. @defaultValue this.defaultWorkerChoiceStrategy
144 * @returns The key of the worker node.
145 * @throws {@link https://nodejs.org/api/errors.html#class-error} If after computed retries the worker node key is null or undefined.
148 workerChoiceStrategy
: WorkerChoiceStrategy
= this
149 .defaultWorkerChoiceStrategy
151 return this.executeStrategy(
152 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
153 this.workerChoiceStrategies
.get(workerChoiceStrategy
)!
158 * Executes the given worker choice strategy.
159 * @param workerChoiceStrategy - The worker choice strategy.
160 * @returns The key of the worker node.
161 * @throws {@link https://nodejs.org/api/errors.html#class-error} If after computed retries the worker node key is null or undefined.
163 private executeStrategy (workerChoiceStrategy
: IWorkerChoiceStrategy
): number {
164 let workerNodeKey
: number | undefined
168 workerNodeKey
= workerChoiceStrategy
.choose()
169 if (workerNodeKey
== null && chooseCount
> 0) {
174 } while (workerNodeKey
== null && retriesCount
< this.retries
)
175 if (workerNodeKey
== null) {
177 `Worker node key chosen is null or undefined after ${retriesCount.toString()} retries`
184 * Removes the worker node key from the active worker choice strategies in the context.
185 * @param workerNodeKey - The worker node key.
186 * @returns `true` if the removal is successful, `false` otherwise.
188 public remove (workerNodeKey
: number): boolean {
190 this.workerChoiceStrategies
,
191 ([_
, workerChoiceStrategy
]) => workerChoiceStrategy
.remove(workerNodeKey
)
196 * Sets the active worker choice strategies in the context options.
197 * @param opts - The worker choice strategy options.
199 public setOptions (opts
: WorkerChoiceStrategyOptions
| undefined): void {
200 for (const workerChoiceStrategy
of this.workerChoiceStrategies
.values()) {
201 workerChoiceStrategy
.setOptions(opts
)
206 * Synchronizes the active worker choice strategies in the context with the given worker choice strategies.
207 * @param workerChoiceStrategies - The worker choice strategies to synchronize.
208 * @param opts - The worker choice strategy options.
210 public syncWorkerChoiceStrategies (
211 workerChoiceStrategies
: Set
<WorkerChoiceStrategy
>,
212 opts
?: WorkerChoiceStrategyOptions
214 for (const workerChoiceStrategy
of this.workerChoiceStrategies
.keys()) {
215 if (!workerChoiceStrategies
.has(workerChoiceStrategy
)) {
216 this.removeWorkerChoiceStrategy(workerChoiceStrategy
)
219 for (const workerChoiceStrategy
of workerChoiceStrategies
) {
220 if (!this.workerChoiceStrategies
.has(workerChoiceStrategy
)) {
221 this.addWorkerChoiceStrategy(workerChoiceStrategy
, this.pool
, opts
)
224 this.workerChoiceStrategiesPolicy
= buildWorkerChoiceStrategiesPolicy(
225 this.workerChoiceStrategies
227 this.workerChoiceStrategiesTaskStatisticsRequirements
=
228 buildWorkerChoiceStrategiesTaskStatisticsRequirements(
229 this.workerChoiceStrategies
234 * Adds a worker choice strategy to the context.
235 * @param workerChoiceStrategy - The worker choice strategy to add.
236 * @param pool - The pool instance.
237 * @param opts - The worker choice strategy options.
238 * @returns The worker choice strategies.
240 private addWorkerChoiceStrategy (
241 workerChoiceStrategy
: WorkerChoiceStrategy
,
242 pool
: IPool
<Worker
, Data
, Response
>,
243 opts
?: WorkerChoiceStrategyOptions
244 ): Map
<WorkerChoiceStrategy
, IWorkerChoiceStrategy
> {
245 if (!this.workerChoiceStrategies
.has(workerChoiceStrategy
)) {
246 return this.workerChoiceStrategies
.set(
247 workerChoiceStrategy
,
248 getWorkerChoiceStrategy
<Worker
, Data
, Response
>(
249 workerChoiceStrategy
,
256 return this.workerChoiceStrategies
260 * Removes a worker choice strategy from the context.
261 * @param workerChoiceStrategy - The worker choice strategy to remove.
262 * @returns `true` if the worker choice strategy is removed, `false` otherwise.
264 private removeWorkerChoiceStrategy (
265 workerChoiceStrategy
: WorkerChoiceStrategy
267 return this.workerChoiceStrategies
.delete(workerChoiceStrategy
)