Commit | Line | Data |
---|---|---|
3c93feb9 JB |
1 | import { |
2 | DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS, | |
3 | DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS | |
4 | } from '../../utils' | |
058a9457 JB |
5 | import type { IPool } from '../pool' |
6 | import type { IWorker } from '../worker' | |
7 | import { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy' | |
8 | import type { | |
9 | IWorkerChoiceStrategy, | |
b1aae695 | 10 | StrategyPolicy, |
05302647 | 11 | TaskStatisticsRequirements, |
058a9457 JB |
12 | WorkerChoiceStrategyOptions |
13 | } from './selection-strategies-types' | |
14 | ||
15 | /** | |
16 | * Selects the worker with the least ELU. | |
17 | * | |
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. | |
058a9457 JB |
21 | */ |
22 | export class LeastEluWorkerChoiceStrategy< | |
23 | Worker extends IWorker, | |
24 | Data = unknown, | |
25 | Response = unknown | |
26 | > | |
27 | extends AbstractWorkerChoiceStrategy<Worker, Data, Response> | |
28 | implements IWorkerChoiceStrategy { | |
b1aae695 JB |
29 | /** @inheritDoc */ |
30 | public readonly strategyPolicy: StrategyPolicy = { | |
31 | dynamicWorkerUsage: false, | |
32 | dynamicWorkerReady: true | |
33 | } | |
34 | ||
058a9457 | 35 | /** @inheritDoc */ |
05302647 | 36 | public readonly taskStatisticsRequirements: TaskStatisticsRequirements = { |
3c93feb9 JB |
37 | runTime: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS, |
38 | waitTime: DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS, | |
5df69fab JB |
39 | elu: { |
40 | aggregate: true, | |
41 | average: false, | |
42 | median: false | |
43 | } | |
058a9457 JB |
44 | } |
45 | ||
46 | /** @inheritDoc */ | |
47 | public constructor ( | |
48 | pool: IPool<Worker, Data, Response>, | |
49 | opts: WorkerChoiceStrategyOptions = DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS | |
50 | ) { | |
51 | super(pool, opts) | |
e460940e | 52 | this.setTaskStatisticsRequirements(this.opts) |
058a9457 JB |
53 | } |
54 | ||
55 | /** @inheritDoc */ | |
56 | public reset (): boolean { | |
57 | return true | |
58 | } | |
59 | ||
60 | /** @inheritDoc */ | |
61 | public update (): boolean { | |
db703c75 JB |
62 | return true |
63 | } | |
64 | ||
65 | /** @inheritDoc */ | |
b1aae695 JB |
66 | public choose (): number | undefined { |
67 | const chosenWorkerNodeKey = this.leastEluNextWorkerNodeKey() | |
68 | this.assignChosenWorkerNodeKey(chosenWorkerNodeKey) | |
69 | return this.nextWorkerNodeKey | |
9b106837 JB |
70 | } |
71 | ||
72 | /** @inheritDoc */ | |
73 | public remove (): boolean { | |
74 | return true | |
75 | } | |
76 | ||
b1aae695 | 77 | private leastEluNextWorkerNodeKey (): number | undefined { |
cdb517b3 | 78 | let minWorkerElu = Infinity |
b1aae695 | 79 | let chosenWorkerNodeKey: number | undefined |
058a9457 | 80 | for (const [workerNodeKey, workerNode] of this.pool.workerNodes.entries()) { |
465b2940 | 81 | const workerUsage = workerNode.usage |
98e72cda | 82 | const workerElu = workerUsage.elu?.active?.aggregate ?? 0 |
8990357d | 83 | if (this.isWorkerNodeEligible(workerNodeKey) && workerElu === 0) { |
b1aae695 | 84 | chosenWorkerNodeKey = workerNodeKey |
5ea80606 | 85 | break |
19dbc45b | 86 | } else if ( |
8990357d | 87 | this.isWorkerNodeEligible(workerNodeKey) && |
19dbc45b JB |
88 | workerElu < minWorkerElu |
89 | ) { | |
cdb517b3 | 90 | minWorkerElu = workerElu |
b1aae695 | 91 | chosenWorkerNodeKey = workerNodeKey |
058a9457 JB |
92 | } |
93 | } | |
b1aae695 | 94 | return chosenWorkerNodeKey |
058a9457 JB |
95 | } |
96 | } |