refactor: move worker choice instance helper into the context class
[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> {
3300e7bc 27 private workerChoiceStrategy: IWorkerChoiceStrategy<Worker, Data, Response>
bdaf31cd
JB
28
29 /**
30 * Worker choice strategy context constructor.
31 *
38e795c1 32 * @param pool - The pool instance.
c923ce56 33 * @param createWorkerCallback - The worker creation callback for dynamic pool.
38e795c1 34 * @param workerChoiceStrategy - The worker choice strategy.
bdaf31cd
JB
35 */
36 public constructor (
3300e7bc 37 pool: IPoolInternal<Worker, Data, Response>,
c923ce56 38 private readonly createWorkerCallback: () => number,
b2b1d84e 39 private workerChoiceStrategyType: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
bdaf31cd 40 ) {
1086026a 41 this.execute.bind(this)
51fe3d3c 42 this.workerChoiceStrategy = this.getWorkerChoiceStrategy(
3300e7bc 43 pool,
6e7ad9cb 44 this.workerChoiceStrategyType
3300e7bc 45 )
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 {
54 return this.workerChoiceStrategy.requiredStatistics
55 }
56
bdaf31cd 57 /**
bdede008 58 * Sets the worker choice strategy to use in the context.
bdaf31cd 59 *
38e795c1 60 * @param workerChoiceStrategy - The worker choice strategy to set.
bdaf31cd
JB
61 */
62 public setWorkerChoiceStrategy (
3300e7bc 63 pool: IPoolInternal<Worker, Data, Response>,
bdaf31cd
JB
64 workerChoiceStrategy: WorkerChoiceStrategy
65 ): void {
b2b1d84e
JB
66 if (this.workerChoiceStrategyType === workerChoiceStrategy) {
67 this.workerChoiceStrategy?.reset()
68 } else {
69 this.workerChoiceStrategyType = workerChoiceStrategy
51fe3d3c
JB
70 this.workerChoiceStrategy = this.getWorkerChoiceStrategy(
71 pool,
72 this.workerChoiceStrategyType
73 )
b2b1d84e 74 }
bdaf31cd
JB
75 }
76
77 /**
51fe3d3c 78 * Executes the worker choice strategy algorithm in the context.
bdaf31cd 79 *
c923ce56 80 * @returns The key of the chosen one.
bdaf31cd 81 */
c923ce56 82 public execute (): number {
9cd39dd4 83 if (
ccd49f03 84 this.workerChoiceStrategy.isDynamicPool &&
3300e7bc
JB
85 !this.workerChoiceStrategy.pool.full &&
86 this.workerChoiceStrategy.pool.findFreeWorkerKey() === -1
9cd39dd4
JB
87 ) {
88 return this.createWorkerCallback()
89 }
bdaf31cd
JB
90 return this.workerChoiceStrategy.choose()
91 }
97a2abc3
JB
92
93 /**
51fe3d3c 94 * Removes a worker from the worker choice strategy in the context.
97a2abc3
JB
95 *
96 * @param workerKey - The key of the worker to remove.
97 * @returns `true` if the removal is successful, `false` otherwise.
98 */
99 public remove (workerKey: number): boolean {
100 return this.workerChoiceStrategy.remove(workerKey)
101 }
51fe3d3c
JB
102
103 /**
104 * Gets the worker choice strategy instance.
105 *
106 * @param pool - The pool instance.
107 * @param workerChoiceStrategy - The worker choice strategy.
108 * @returns The worker choice strategy instance.
109 */
110 private getWorkerChoiceStrategy (
111 pool: IPoolInternal<Worker, Data, Response>,
112 workerChoiceStrategy: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
113 ): IWorkerChoiceStrategy<Worker, Data, Response> {
114 switch (workerChoiceStrategy) {
115 case WorkerChoiceStrategies.ROUND_ROBIN:
116 return new RoundRobinWorkerChoiceStrategy<Worker, Data, Response>(pool)
117 case WorkerChoiceStrategies.LESS_USED:
118 return new LessUsedWorkerChoiceStrategy<Worker, Data, Response>(pool)
119 case WorkerChoiceStrategies.LESS_BUSY:
120 return new LessBusyWorkerChoiceStrategy<Worker, Data, Response>(pool)
121 case WorkerChoiceStrategies.FAIR_SHARE:
122 return new FairShareWorkerChoiceStrategy<Worker, Data, Response>(pool)
123 case WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN:
124 return new WeightedRoundRobinWorkerChoiceStrategy<
125 Worker,
126 Data,
127 Response
128 >(pool)
129 default:
130 throw new Error(
131 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
132 `Worker choice strategy '${workerChoiceStrategy}' not found`
133 )
134 }
135 }
bdaf31cd 136}