fix: ensure worker removal impact is propated to worker choice strategy
[poolifier.git] / src / pools / selection-strategies / worker-choice-strategy-context.ts
1 import type { IPoolInternal } from '../pool-internal'
2 import { PoolType } from '../pool-internal'
3 import type { IPoolWorker } from '../pool-worker'
4 import { DynamicPoolWorkerChoiceStrategy } from './dynamic-pool-worker-choice-strategy'
5 import type {
6 IWorkerChoiceStrategy,
7 RequiredStatistics,
8 WorkerChoiceStrategy
9 } from './selection-strategies-types'
10 import { WorkerChoiceStrategies } from './selection-strategies-types'
11 import { getWorkerChoiceStrategy } from './selection-strategies-utils'
12
13 /**
14 * The worker choice strategy context.
15 *
16 * @typeParam Worker - Type of worker.
17 * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
18 * @typeParam Response - Type of response of execution. This can only be serializable data.
19 */
20 export class WorkerChoiceStrategyContext<
21 Worker extends IPoolWorker,
22 Data,
23 Response
24 > {
25 private workerChoiceStrategy!: IWorkerChoiceStrategy
26
27 /**
28 * Worker choice strategy context constructor.
29 *
30 * @param pool - The pool instance.
31 * @param createWorkerCallback - The worker creation callback for dynamic pool.
32 * @param workerChoiceStrategy - The worker choice strategy.
33 */
34 public constructor (
35 private readonly pool: IPoolInternal<Worker, Data, Response>,
36 private readonly createWorkerCallback: () => number,
37 workerChoiceStrategy: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
38 ) {
39 this.setWorkerChoiceStrategy(workerChoiceStrategy)
40 }
41
42 /**
43 * Gets the worker choice strategy instance specific to the pool type.
44 *
45 * @param workerChoiceStrategy - The worker choice strategy.
46 * @returns The worker choice strategy instance for the pool type.
47 */
48 private getPoolWorkerChoiceStrategy (
49 workerChoiceStrategy: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
50 ): IWorkerChoiceStrategy {
51 if (this.pool.type === PoolType.DYNAMIC) {
52 return new DynamicPoolWorkerChoiceStrategy(
53 this.pool,
54 this.createWorkerCallback,
55 workerChoiceStrategy
56 )
57 }
58 return getWorkerChoiceStrategy(this.pool, workerChoiceStrategy)
59 }
60
61 /**
62 * Gets the worker choice strategy used in the context.
63 *
64 * @returns The worker choice strategy.
65 * @deprecated Scheduled removal.
66 */
67 public getWorkerChoiceStrategy (): IWorkerChoiceStrategy {
68 return this.workerChoiceStrategy
69 }
70
71 /**
72 * Gets the worker choice strategy required statistics.
73 *
74 * @returns The required statistics.
75 */
76 public getRequiredStatistics (): RequiredStatistics {
77 return this.workerChoiceStrategy.requiredStatistics
78 }
79
80 /**
81 * Sets the worker choice strategy to use in the context.
82 *
83 * @param workerChoiceStrategy - The worker choice strategy to set.
84 */
85 public setWorkerChoiceStrategy (
86 workerChoiceStrategy: WorkerChoiceStrategy
87 ): void {
88 this.workerChoiceStrategy?.reset()
89 this.workerChoiceStrategy =
90 this.getPoolWorkerChoiceStrategy(workerChoiceStrategy)
91 }
92
93 /**
94 * Chooses a worker with the underlying selection strategy.
95 *
96 * @returns The key of the chosen one.
97 */
98 public execute (): number {
99 return this.workerChoiceStrategy.choose()
100 }
101
102 /**
103 * Removes a worker in the underlying selection strategy internals.
104 *
105 * @param workerKey - The key of the worker to remove.
106 * @returns `true` if the removal is successful, `false` otherwise.
107 */
108 public remove (workerKey: number): boolean {
109 return this.workerChoiceStrategy.remove(workerKey)
110 }
111 }