fix: properly handle dynamic pool with zero minimum size
[poolifier.git] / src / pools / selection-strategies / least-used-worker-choice-strategy.ts
CommitLineData
d35e5717
JB
1import type { IPool } from '../pool.js'
2import type { IWorker } from '../worker.js'
3import { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy.js'
2fc5cae3
JB
4import type {
5 IWorkerChoiceStrategy,
39618ede 6 WorkerChoiceStrategyOptions
d35e5717 7} from './selection-strategies-types.js'
bdaf31cd
JB
8
9/**
e4543b14 10 * Selects the least used worker.
bdaf31cd 11 *
38e795c1 12 * @typeParam Worker - Type of worker which manages the strategy.
e102732c
JB
13 * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
14 * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
bdaf31cd 15 */
e4543b14 16export class LeastUsedWorkerChoiceStrategy<
f06e48d8 17 Worker extends IWorker,
b2b1d84e
JB
18 Data = unknown,
19 Response = unknown
bf90656c
JB
20 >
21 extends AbstractWorkerChoiceStrategy<Worker, Data, Response>
17393ac8 22 implements IWorkerChoiceStrategy {
2fc5cae3
JB
23 /** @inheritDoc */
24 public constructor (
25 pool: IPool<Worker, Data, Response>,
39618ede 26 opts?: WorkerChoiceStrategyOptions
2fc5cae3
JB
27 ) {
28 super(pool, opts)
2fc5cae3
JB
29 }
30
afc003b2 31 /** @inheritDoc */
a6f7f1b4 32 public reset (): boolean {
ea7a90d3
JB
33 return true
34 }
35
138d29a8
JB
36 /** @inheritDoc */
37 public update (): boolean {
db703c75
JB
38 return true
39 }
40
41 /** @inheritDoc */
b1aae695 42 public choose (): number | undefined {
baca80f7 43 this.setPreviousWorkerNodeKey(this.nextWorkerNodeKey)
fce028d6 44 this.nextWorkerNodeKey = this.leastUsedNextWorkerNodeKey()
b1aae695 45 return this.nextWorkerNodeKey
9b106837
JB
46 }
47
48 /** @inheritDoc */
49 public remove (): boolean {
50 return true
51 }
52
b1aae695 53 private leastUsedNextWorkerNodeKey (): number | undefined {
e44639e9
JB
54 if (this.pool.workerNodes.length === 0) {
55 return undefined
56 }
f3a91bac
JB
57 return this.pool.workerNodes.reduce(
58 (minWorkerNodeKey, workerNode, workerNodeKey, workerNodes) => {
ae3ab61d
JB
59 return this.isWorkerNodeReady(workerNodeKey) &&
60 workerNode.usage.tasks.executed +
61 workerNode.usage.tasks.executing +
62 workerNode.usage.tasks.queued <
63 workerNodes[minWorkerNodeKey].usage.tasks.executed +
64 workerNodes[minWorkerNodeKey].usage.tasks.executing +
65 workerNodes[minWorkerNodeKey].usage.tasks.queued
f3a91bac
JB
66 ? workerNodeKey
67 : minWorkerNodeKey
68 },
69 0
70 )
97a2abc3 71 }
bdaf31cd 72}