refactor: add PoolEvents/PoolEvent types
[poolifier.git] / src / pools / selection-strategies / worker-choice-strategy-context.ts
1 import type { IPoolInternal } from '../pool-internal'
2 import type { IPoolWorker } from '../pool-worker'
3 import { FairShareWorkerChoiceStrategy } from './fair-share-worker-choice-strategy'
4 import { LessBusyWorkerChoiceStrategy } from './less-busy-worker-choice-strategy'
5 import { LessUsedWorkerChoiceStrategy } from './less-used-worker-choice-strategy'
6 import { RoundRobinWorkerChoiceStrategy } from './round-robin-worker-choice-strategy'
7 import type {
8 IWorkerChoiceStrategy,
9 RequiredStatistics,
10 WorkerChoiceStrategy
11 } from './selection-strategies-types'
12 import { WorkerChoiceStrategies } from './selection-strategies-types'
13 import { WeightedRoundRobinWorkerChoiceStrategy } from './weighted-round-robin-worker-choice-strategy'
14
15 /**
16 * The worker choice strategy context.
17 *
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.
21 */
22 export class WorkerChoiceStrategyContext<
23 Worker extends IPoolWorker,
24 Data = unknown,
25 Response = unknown
26 > {
27 private readonly workerChoiceStrategies: Map<
28 WorkerChoiceStrategy,
29 IWorkerChoiceStrategy
30 >
31
32 /**
33 * Worker choice strategy context constructor.
34 *
35 * @param pool - The pool instance.
36 * @param createWorkerCallback - The worker creation callback for dynamic pool.
37 * @param workerChoiceStrategy - The worker choice strategy.
38 */
39 public constructor (
40 pool: IPoolInternal<Worker, Data, Response>,
41 private workerChoiceStrategyType: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
42 ) {
43 this.execute.bind(this)
44 this.workerChoiceStrategies = new Map<
45 WorkerChoiceStrategy,
46 IWorkerChoiceStrategy
47 >([
48 [
49 WorkerChoiceStrategies.ROUND_ROBIN,
50 new RoundRobinWorkerChoiceStrategy<Worker, Data, Response>(pool)
51 ],
52 [
53 WorkerChoiceStrategies.LESS_USED,
54 new LessUsedWorkerChoiceStrategy<Worker, Data, Response>(pool)
55 ],
56 [
57 WorkerChoiceStrategies.LESS_BUSY,
58 new LessBusyWorkerChoiceStrategy<Worker, Data, Response>(pool)
59 ],
60 [
61 WorkerChoiceStrategies.FAIR_SHARE,
62 new FairShareWorkerChoiceStrategy<Worker, Data, Response>(pool)
63 ],
64 [
65 WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN,
66 new WeightedRoundRobinWorkerChoiceStrategy<Worker, Data, Response>(pool)
67 ]
68 ])
69 }
70
71 /**
72 * Gets the worker choice strategy in the context required statistics.
73 *
74 * @returns The required statistics.
75 */
76 public getRequiredStatistics (): RequiredStatistics {
77 return (
78 this.workerChoiceStrategies.get(
79 this.workerChoiceStrategyType
80 ) as IWorkerChoiceStrategy
81 ).requiredStatistics
82 }
83
84 /**
85 * Sets the worker choice strategy to use in the context.
86 *
87 * @param workerChoiceStrategy - The worker choice strategy to set.
88 */
89 public setWorkerChoiceStrategy (
90 workerChoiceStrategy: WorkerChoiceStrategy
91 ): void {
92 if (this.workerChoiceStrategyType !== workerChoiceStrategy) {
93 this.workerChoiceStrategyType = workerChoiceStrategy
94 }
95 this.workerChoiceStrategies.get(this.workerChoiceStrategyType)?.reset()
96 }
97
98 /**
99 * Executes the worker choice strategy algorithm in the context.
100 *
101 * @returns The key of the chosen one.
102 */
103 public execute (): number {
104 return (
105 this.workerChoiceStrategies.get(
106 this.workerChoiceStrategyType
107 ) as IWorkerChoiceStrategy
108 ).choose()
109 }
110
111 /**
112 * Removes a worker from the worker choice strategy in the context.
113 *
114 * @param workerKey - The key of the worker to remove.
115 * @returns `true` if the removal is successful, `false` otherwise.
116 */
117 public remove (workerKey: number): boolean {
118 return (
119 this.workerChoiceStrategies.get(
120 this.workerChoiceStrategyType
121 ) as IWorkerChoiceStrategy
122 ).remove(workerKey)
123 }
124 }