2 DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS
,
3 buildInternalWorkerChoiceStrategyOptions
5 import type { IPool
} from
'../pool'
6 import type { IWorker
} from
'../worker'
9 InternalWorkerChoiceStrategyOptions
,
10 MeasurementStatisticsRequirements
,
12 TaskStatisticsRequirements
13 } from
'./selection-strategies-types'
16 * Worker choice strategy abstract base class.
18 * @typeParam Worker - Type of worker which manages the strategy.
19 * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
20 * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
22 export abstract class AbstractWorkerChoiceStrategy
<
23 Worker
extends IWorker
,
26 > implements IWorkerChoiceStrategy
{
28 * The next worker node key.
30 protected nextWorkerNodeKey
: number | undefined = 0
33 * The previous worker node key.
35 protected previousWorkerNodeKey
: number = 0
38 public readonly strategyPolicy
: StrategyPolicy
= {
39 dynamicWorkerUsage
: false,
40 dynamicWorkerReady
: true
44 public readonly taskStatisticsRequirements
: TaskStatisticsRequirements
= {
45 runTime
: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS
,
46 waitTime
: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS
,
47 elu
: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS
51 * Constructs a worker choice strategy bound to the pool.
53 * @param pool - The pool instance.
54 * @param opts - The worker choice strategy options.
57 protected readonly pool
: IPool
<Worker
, Data
, Response
>,
58 protected opts
: InternalWorkerChoiceStrategyOptions
60 this.opts
= buildInternalWorkerChoiceStrategyOptions(
61 this.pool
.info
.maxSize
,
64 this.setTaskStatisticsRequirements(this.opts
)
65 this.choose
= this.choose
.bind(this)
68 protected setTaskStatisticsRequirements (
69 opts
: InternalWorkerChoiceStrategyOptions
71 this.toggleMedianMeasurementStatisticsRequirements(
72 this.taskStatisticsRequirements
.runTime
,
73 opts
.runTime
?.median
as boolean
75 this.toggleMedianMeasurementStatisticsRequirements(
76 this.taskStatisticsRequirements
.waitTime
,
77 opts
.waitTime
?.median
as boolean
79 this.toggleMedianMeasurementStatisticsRequirements(
80 this.taskStatisticsRequirements
.elu
,
81 opts
.elu
?.median
as boolean
85 private toggleMedianMeasurementStatisticsRequirements (
86 measurementStatisticsRequirements
: MeasurementStatisticsRequirements
,
89 if (measurementStatisticsRequirements
.average
&& toggleMedian
) {
90 measurementStatisticsRequirements
.average
= false
91 measurementStatisticsRequirements
.median
= toggleMedian
93 if (measurementStatisticsRequirements
.median
&& !toggleMedian
) {
94 measurementStatisticsRequirements
.average
= true
95 measurementStatisticsRequirements
.median
= toggleMedian
99 protected resetWorkerNodeKeyProperties (): void {
100 this.nextWorkerNodeKey
= 0
101 this.previousWorkerNodeKey
= 0
105 public abstract reset (): boolean
108 public abstract update (workerNodeKey
: number): boolean
111 public abstract choose (): number | undefined
114 public abstract remove (workerNodeKey
: number): boolean
117 public setOptions (opts
: InternalWorkerChoiceStrategyOptions
): void {
118 this.opts
= buildInternalWorkerChoiceStrategyOptions(
119 this.pool
.info
.maxSize
,
122 this.setTaskStatisticsRequirements(this.opts
)
126 public hasPoolWorkerNodesReady (): boolean {
127 return this.pool
.workerNodes
.some(workerNode
=> workerNode
.info
.ready
)
131 * Whether the worker node is ready or not.
133 * @param workerNodeKey - The worker node key.
134 * @returns Whether the worker node is ready or not.
136 protected isWorkerNodeReady (workerNodeKey
: number): boolean {
137 return this.pool
.workerNodes
[workerNodeKey
]?.info
?.ready
?? false
141 * Check the next worker node readiness.
143 protected checkNextWorkerNodeReadiness (): void {
144 if (!this.isWorkerNodeReady(this.nextWorkerNodeKey
as number)) {
145 delete this.nextWorkerNodeKey
150 * Gets the worker node task runtime.
151 * If the task statistics require the average runtime, the average runtime is returned.
152 * If the task statistics require the median runtime , the median runtime is returned.
154 * @param workerNodeKey - The worker node key.
155 * @returns The worker node task runtime.
157 protected getWorkerNodeTaskRunTime (workerNodeKey
: number): number {
158 return this.taskStatisticsRequirements
.runTime
.median
159 ? this.pool
.workerNodes
[workerNodeKey
].usage
.runTime
.median
?? 0
160 : this.pool
.workerNodes
[workerNodeKey
].usage
.runTime
.average
?? 0
164 * Gets the worker node task wait time.
165 * If the task statistics require the average wait time, the average wait time is returned.
166 * If the task statistics require the median wait time, the median wait time is returned.
168 * @param workerNodeKey - The worker node key.
169 * @returns The worker node task wait time.
171 protected getWorkerNodeTaskWaitTime (workerNodeKey
: number): number {
172 return this.taskStatisticsRequirements
.waitTime
.median
173 ? this.pool
.workerNodes
[workerNodeKey
].usage
.waitTime
.median
?? 0
174 : this.pool
.workerNodes
[workerNodeKey
].usage
.waitTime
.average
?? 0
178 * Gets the worker node task ELU.
179 * If the task statistics require the average ELU, the average ELU is returned.
180 * If the task statistics require the median ELU, the median ELU is returned.
182 * @param workerNodeKey - The worker node key.
183 * @returns The worker node task ELU.
185 protected getWorkerNodeTaskElu (workerNodeKey
: number): number {
186 return this.taskStatisticsRequirements
.elu
.median
187 ? this.pool
.workerNodes
[workerNodeKey
].usage
.elu
.active
.median
?? 0
188 : this.pool
.workerNodes
[workerNodeKey
].usage
.elu
.active
.average
?? 0
192 * Sets safely the previous worker node key.
194 * @param workerNodeKey - The worker node key.
196 protected setPreviousWorkerNodeKey (workerNodeKey
: number | undefined): void {
197 this.previousWorkerNodeKey
= workerNodeKey
?? this.previousWorkerNodeKey