feat: add tasks queue to pool data structure
[poolifier.git] / src / pools / selection-strategies / worker-choice-strategy-context.ts
1 import type { IPoolInternal } from '../pool-internal'
2 import type { IWorker } from '../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 IWorker,
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 workerChoiceStrategyType - The worker choice strategy.
37 */
38 public constructor (
39 pool: IPoolInternal<Worker, Data, Response>,
40 private workerChoiceStrategyType: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
41 ) {
42 this.execute.bind(this)
43 this.workerChoiceStrategies = new Map<
44 WorkerChoiceStrategy,
45 IWorkerChoiceStrategy
46 >([
47 [
48 WorkerChoiceStrategies.ROUND_ROBIN,
49 new RoundRobinWorkerChoiceStrategy<Worker, Data, Response>(pool)
50 ],
51 [
52 WorkerChoiceStrategies.LESS_USED,
53 new LessUsedWorkerChoiceStrategy<Worker, Data, Response>(pool)
54 ],
55 [
56 WorkerChoiceStrategies.LESS_BUSY,
57 new LessBusyWorkerChoiceStrategy<Worker, Data, Response>(pool)
58 ],
59 [
60 WorkerChoiceStrategies.FAIR_SHARE,
61 new FairShareWorkerChoiceStrategy<Worker, Data, Response>(pool)
62 ],
63 [
64 WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN,
65 new WeightedRoundRobinWorkerChoiceStrategy<Worker, Data, Response>(pool)
66 ]
67 ])
68 }
69
70 /**
71 * Gets the worker choice strategy in the context required statistics.
72 *
73 * @returns The required statistics.
74 */
75 public getRequiredStatistics (): RequiredStatistics {
76 return (
77 this.workerChoiceStrategies.get(
78 this.workerChoiceStrategyType
79 ) as IWorkerChoiceStrategy
80 ).requiredStatistics
81 }
82
83 /**
84 * Sets the worker choice strategy to use in the context.
85 *
86 * @param workerChoiceStrategy - The worker choice strategy to set.
87 */
88 public setWorkerChoiceStrategy (
89 workerChoiceStrategy: WorkerChoiceStrategy
90 ): void {
91 if (this.workerChoiceStrategyType !== workerChoiceStrategy) {
92 this.workerChoiceStrategyType = workerChoiceStrategy
93 }
94 this.workerChoiceStrategies.get(this.workerChoiceStrategyType)?.reset()
95 }
96
97 /**
98 * Executes the worker choice strategy algorithm in the context.
99 *
100 * @returns The key of the worker node.
101 */
102 public execute (): number {
103 return (
104 this.workerChoiceStrategies.get(
105 this.workerChoiceStrategyType
106 ) as IWorkerChoiceStrategy
107 ).choose()
108 }
109
110 /**
111 * Removes a worker node key from the worker choice strategy in the context.
112 *
113 * @param workerNodeKey - The key of the worker node.
114 * @returns `true` if the removal is successful, `false` otherwise.
115 */
116 public remove (workerNodeKey: number): boolean {
117 return (
118 this.workerChoiceStrategies.get(
119 this.workerChoiceStrategyType
120 ) as IWorkerChoiceStrategy
121 ).remove(workerNodeKey)
122 }
123 }