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