build(deps-dev): apply updates
[poolifier.git] / src / pools / selection-strategies / worker-choice-strategy-context.ts
CommitLineData
bdaf31cd 1import type { IPoolInternal } from '../pool-internal'
ea7a90d3 2import type { IPoolWorker } from '../pool-worker'
51fe3d3c
JB
3import { FairShareWorkerChoiceStrategy } from './fair-share-worker-choice-strategy'
4import { LessBusyWorkerChoiceStrategy } from './less-busy-worker-choice-strategy'
5import { LessUsedWorkerChoiceStrategy } from './less-used-worker-choice-strategy'
6import { RoundRobinWorkerChoiceStrategy } from './round-robin-worker-choice-strategy'
bdaf31cd
JB
7import type {
8 IWorkerChoiceStrategy,
97a2abc3 9 RequiredStatistics,
bdaf31cd
JB
10 WorkerChoiceStrategy
11} from './selection-strategies-types'
12import { WorkerChoiceStrategies } from './selection-strategies-types'
51fe3d3c 13import { WeightedRoundRobinWorkerChoiceStrategy } from './weighted-round-robin-worker-choice-strategy'
bdaf31cd
JB
14
15/**
16 * The worker choice strategy context.
17 *
38e795c1
JB
18 * @typeParam Worker - Type of worker.
19 * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
20 * @typeParam Response - Type of response of execution. This can only be serializable data.
bdaf31cd
JB
21 */
22export class WorkerChoiceStrategyContext<
ea7a90d3 23 Worker extends IPoolWorker,
b2b1d84e
JB
24 Data = unknown,
25 Response = unknown
bdaf31cd 26> {
95c83464
JB
27 private readonly workerChoiceStrategies = new Map<
28 WorkerChoiceStrategy,
29 IWorkerChoiceStrategy<Worker, Data, Response>
30 >()
bdaf31cd
JB
31
32 /**
33 * Worker choice strategy context constructor.
34 *
38e795c1 35 * @param pool - The pool instance.
c923ce56 36 * @param createWorkerCallback - The worker creation callback for dynamic pool.
38e795c1 37 * @param workerChoiceStrategy - The worker choice strategy.
bdaf31cd
JB
38 */
39 public constructor (
3300e7bc 40 pool: IPoolInternal<Worker, Data, Response>,
c923ce56 41 private readonly createWorkerCallback: () => number,
b2b1d84e 42 private workerChoiceStrategyType: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
bdaf31cd 43 ) {
1086026a 44 this.execute.bind(this)
95c83464 45 this.registerWorkerChoiceStrategy(pool, workerChoiceStrategyType)
bdaf31cd
JB
46 }
47
97a2abc3 48 /**
51fe3d3c 49 * Gets the worker choice strategy in the context required statistics.
97a2abc3
JB
50 *
51 * @returns The required statistics.
52 */
53 public getRequiredStatistics (): RequiredStatistics {
95c83464
JB
54 return (
55 this.workerChoiceStrategies.get(
56 this.workerChoiceStrategyType
57 ) as IWorkerChoiceStrategy<Worker, Data, Response>
58 ).requiredStatistics
97a2abc3
JB
59 }
60
bdaf31cd 61 /**
bdede008 62 * Sets the worker choice strategy to use in the context.
bdaf31cd 63 *
38e795c1 64 * @param workerChoiceStrategy - The worker choice strategy to set.
bdaf31cd
JB
65 */
66 public setWorkerChoiceStrategy (
3300e7bc 67 pool: IPoolInternal<Worker, Data, Response>,
bdaf31cd
JB
68 workerChoiceStrategy: WorkerChoiceStrategy
69 ): void {
b2b1d84e 70 if (this.workerChoiceStrategyType === workerChoiceStrategy) {
95c83464 71 this.workerChoiceStrategies.get(workerChoiceStrategy)?.reset()
b2b1d84e
JB
72 } else {
73 this.workerChoiceStrategyType = workerChoiceStrategy
95c83464 74 this.registerWorkerChoiceStrategy(pool, workerChoiceStrategy)
b2b1d84e 75 }
bdaf31cd
JB
76 }
77
78 /**
51fe3d3c 79 * Executes the worker choice strategy algorithm in the context.
bdaf31cd 80 *
c923ce56 81 * @returns The key of the chosen one.
bdaf31cd 82 */
c923ce56 83 public execute (): number {
95c83464
JB
84 const workerChoiceStrategy = this.workerChoiceStrategies.get(
85 this.workerChoiceStrategyType
86 ) as IWorkerChoiceStrategy<Worker, Data, Response>
9cd39dd4 87 if (
95c83464
JB
88 workerChoiceStrategy.isDynamicPool &&
89 !workerChoiceStrategy.pool.full &&
90 workerChoiceStrategy.pool.findFreeWorkerKey() === -1
9cd39dd4
JB
91 ) {
92 return this.createWorkerCallback()
93 }
95c83464 94 return workerChoiceStrategy.choose()
bdaf31cd 95 }
97a2abc3
JB
96
97 /**
51fe3d3c 98 * Removes a worker from the worker choice strategy in the context.
97a2abc3
JB
99 *
100 * @param workerKey - The key of the worker to remove.
101 * @returns `true` if the removal is successful, `false` otherwise.
102 */
103 public remove (workerKey: number): boolean {
95c83464
JB
104 return (
105 this.workerChoiceStrategies.get(
106 this.workerChoiceStrategyType
107 ) as IWorkerChoiceStrategy<Worker, Data, Response>
108 ).remove(workerKey)
109 }
110
111 private registerWorkerChoiceStrategy (
112 pool: IPoolInternal<Worker, Data, Response>,
113 workerChoiceStrategy: WorkerChoiceStrategy
114 ): void {
115 if (!this.workerChoiceStrategies.has(workerChoiceStrategy)) {
116 this.workerChoiceStrategies.set(
117 workerChoiceStrategy,
118 this.getWorkerChoiceStrategy(pool, workerChoiceStrategy)
119 )
120 }
97a2abc3 121 }
51fe3d3c
JB
122
123 /**
124 * Gets the worker choice strategy instance.
125 *
126 * @param pool - The pool instance.
127 * @param workerChoiceStrategy - The worker choice strategy.
128 * @returns The worker choice strategy instance.
129 */
130 private getWorkerChoiceStrategy (
131 pool: IPoolInternal<Worker, Data, Response>,
132 workerChoiceStrategy: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
133 ): IWorkerChoiceStrategy<Worker, Data, Response> {
134 switch (workerChoiceStrategy) {
135 case WorkerChoiceStrategies.ROUND_ROBIN:
136 return new RoundRobinWorkerChoiceStrategy<Worker, Data, Response>(pool)
137 case WorkerChoiceStrategies.LESS_USED:
138 return new LessUsedWorkerChoiceStrategy<Worker, Data, Response>(pool)
139 case WorkerChoiceStrategies.LESS_BUSY:
140 return new LessBusyWorkerChoiceStrategy<Worker, Data, Response>(pool)
141 case WorkerChoiceStrategies.FAIR_SHARE:
142 return new FairShareWorkerChoiceStrategy<Worker, Data, Response>(pool)
143 case WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN:
144 return new WeightedRoundRobinWorkerChoiceStrategy<
145 Worker,
146 Data,
147 Response
148 >(pool)
149 default:
150 throw new Error(
151 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
152 `Worker choice strategy '${workerChoiceStrategy}' not found`
153 )
154 }
155 }
bdaf31cd 156}