build(deps-dev): apply updates
[poolifier.git] / src / pools / selection-strategies / abstract-worker-choice-strategy.ts
CommitLineData
e9ed6eee 1import type { IPool } from '../pool.js'
bcfb06ce 2import { DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS } from '../utils.js'
d35e5717 3import type { IWorker } from '../worker.js'
10fcfaf4
JB
4import type {
5 IWorkerChoiceStrategy,
6c6afb84 6 StrategyPolicy,
39618ede 7 TaskStatisticsRequirements,
3a502712 8 WorkerChoiceStrategyOptions,
d35e5717 9} from './selection-strategies-types.js'
763abb1c
JB
10import {
11 buildWorkerChoiceStrategyOptions,
3a502712 12 toggleMedianMeasurementStatisticsRequirements,
763abb1c 13} from './selection-strategies-utils.js'
bdaf31cd
JB
14
15/**
9cd39dd4 16 * Worker choice strategy abstract base class.
38e795c1 17 * @typeParam Worker - Type of worker which manages the strategy.
e102732c
JB
18 * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
19 * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
bdaf31cd
JB
20 */
21export abstract class AbstractWorkerChoiceStrategy<
f06e48d8 22 Worker extends IWorker,
b2b1d84e
JB
23 Data = unknown,
24 Response = unknown
17393ac8 25> implements IWorkerChoiceStrategy {
d33be430 26 /**
9b106837 27 * The next worker node key.
d33be430 28 */
b1aae695 29 protected nextWorkerNodeKey: number | undefined = 0
d33be430 30
7c7bb289
JB
31 /**
32 * The previous worker node key.
33 */
c63a35a0 34 protected previousWorkerNodeKey = 0
7c7bb289 35
6c6afb84
JB
36 /** @inheritDoc */
37 public readonly strategyPolicy: StrategyPolicy = {
b1aae695 38 dynamicWorkerUsage: false,
3a502712 39 dynamicWorkerReady: true,
6c6afb84
JB
40 }
41
afc003b2 42 /** @inheritDoc */
87de9ff5 43 public readonly taskStatisticsRequirements: TaskStatisticsRequirements = {
3c93feb9
JB
44 runTime: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS,
45 waitTime: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS,
3a502712 46 elu: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS,
10fcfaf4 47 }
bdaf31cd
JB
48
49 /**
6533c3e6 50 * Constructs a worker choice strategy bound to the pool.
38e795c1 51 * @param pool - The pool instance.
da309861 52 * @param opts - The worker choice strategy options.
bdaf31cd
JB
53 */
54 public constructor (
c4855468 55 protected readonly pool: IPool<Worker, Data, Response>,
39618ede 56 protected opts?: WorkerChoiceStrategyOptions
b8f3418c 57 ) {
7254e419 58 this.choose = this.choose.bind(this)
04d875a3 59 this.setOptions(this.opts)
b8f3418c 60 }
bdaf31cd 61
932fc8be 62 protected setTaskStatisticsRequirements (
39618ede 63 opts: WorkerChoiceStrategyOptions | undefined
932fc8be 64 ): void {
763abb1c 65 toggleMedianMeasurementStatisticsRequirements(
57441b79 66 this.taskStatisticsRequirements.runTime,
67f3f2d6 67 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
39618ede 68 opts!.runTime!.median
57441b79 69 )
763abb1c 70 toggleMedianMeasurementStatisticsRequirements(
57441b79 71 this.taskStatisticsRequirements.waitTime,
67f3f2d6 72 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
39618ede 73 opts!.waitTime!.median
57441b79 74 )
763abb1c 75 toggleMedianMeasurementStatisticsRequirements(
57441b79 76 this.taskStatisticsRequirements.elu,
67f3f2d6 77 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
39618ede 78 opts!.elu!.median
57441b79
JB
79 )
80 }
81
39a43af7
JB
82 protected resetWorkerNodeKeyProperties (): void {
83 this.nextWorkerNodeKey = 0
84 this.previousWorkerNodeKey = 0
85 }
86
afc003b2 87 /** @inheritDoc */
a6f7f1b4 88 public abstract reset (): boolean
ea7a90d3 89
138d29a8 90 /** @inheritDoc */
a4958de2 91 public abstract update (workerNodeKey: number): boolean
138d29a8 92
afc003b2 93 /** @inheritDoc */
b1aae695 94 public abstract choose (): number | undefined
97a2abc3 95
afc003b2 96 /** @inheritDoc */
f06e48d8 97 public abstract remove (workerNodeKey: number): boolean
a20f0ba5
JB
98
99 /** @inheritDoc */
39618ede
JB
100 public setOptions (opts: WorkerChoiceStrategyOptions | undefined): void {
101 this.opts = buildWorkerChoiceStrategyOptions<Worker, Data, Response>(
102 this.pool,
00e1bdeb
JB
103 opts
104 )
65ab8dcc 105 this.setTaskStatisticsRequirements(this.opts)
a20f0ba5 106 }
cb70b19d 107
d4ddb68b
JB
108 /**
109 * Whether the worker node is ready or not.
d4ddb68b
JB
110 * @param workerNodeKey - The worker node key.
111 * @returns Whether the worker node is ready or not.
112 */
ae3ab61d 113 protected isWorkerNodeReady (workerNodeKey: number): boolean {
535fd8d5 114 return this.pool.workerNodes[workerNodeKey]?.info?.ready ?? false
19dbc45b
JB
115 }
116
a38b62f1 117 /**
8e8d9101 118 * Check the next worker node key.
a38b62f1 119 */
8e8d9101
JB
120 protected checkNextWorkerNodeKey (): void {
121 if (
122 this.nextWorkerNodeKey != null &&
123 (this.nextWorkerNodeKey < 0 ||
124 !this.isWorkerNodeReady(this.nextWorkerNodeKey))
125 ) {
a38b62f1
JB
126 delete this.nextWorkerNodeKey
127 }
128 }
129
f6b641d6 130 /**
f3a91bac 131 * Gets the worker node task runtime.
932fc8be 132 * If the task statistics require the average runtime, the average runtime is returned.
e0843544 133 * If the task statistics require the median runtime, the median runtime is returned.
f6b641d6 134 * @param workerNodeKey - The worker node key.
f3a91bac 135 * @returns The worker node task runtime.
f6b641d6 136 */
f3a91bac 137 protected getWorkerNodeTaskRunTime (workerNodeKey: number): number {
932fc8be 138 return this.taskStatisticsRequirements.runTime.median
46b0bb09
JB
139 ? this.pool.workerNodes[workerNodeKey].usage.runTime.median ?? 0
140 : this.pool.workerNodes[workerNodeKey].usage.runTime.average ?? 0
f6b641d6
JB
141 }
142
ef680bb8 143 /**
f3a91bac 144 * Gets the worker node task wait time.
932fc8be
JB
145 * If the task statistics require the average wait time, the average wait time is returned.
146 * If the task statistics require the median wait time, the median wait time is returned.
ef680bb8 147 * @param workerNodeKey - The worker node key.
f3a91bac 148 * @returns The worker node task wait time.
ef680bb8 149 */
f3a91bac 150 protected getWorkerNodeTaskWaitTime (workerNodeKey: number): number {
932fc8be 151 return this.taskStatisticsRequirements.waitTime.median
46b0bb09
JB
152 ? this.pool.workerNodes[workerNodeKey].usage.waitTime.median ?? 0
153 : this.pool.workerNodes[workerNodeKey].usage.waitTime.average ?? 0
ef680bb8
JB
154 }
155
5df69fab 156 /**
f3a91bac 157 * Gets the worker node task ELU.
9adcefab
JB
158 * If the task statistics require the average ELU, the average ELU is returned.
159 * If the task statistics require the median ELU, the median ELU is returned.
5df69fab 160 * @param workerNodeKey - The worker node key.
f3a91bac 161 * @returns The worker node task ELU.
5df69fab 162 */
f3a91bac 163 protected getWorkerNodeTaskElu (workerNodeKey: number): number {
5df69fab 164 return this.taskStatisticsRequirements.elu.median
46b0bb09
JB
165 ? this.pool.workerNodes[workerNodeKey].usage.elu.active.median ?? 0
166 : this.pool.workerNodes[workerNodeKey].usage.elu.active.average ?? 0
5df69fab
JB
167 }
168
baca80f7
JB
169 /**
170 * Sets safely the previous worker node key.
baca80f7
JB
171 * @param workerNodeKey - The worker node key.
172 */
173 protected setPreviousWorkerNodeKey (workerNodeKey: number | undefined): void {
8e8d9101
JB
174 this.previousWorkerNodeKey =
175 workerNodeKey != null && workerNodeKey >= 0
176 ? workerNodeKey
177 : this.previousWorkerNodeKey
baca80f7 178 }
bdaf31cd 179}