d98732d66882a66e961a04dc49e4241ae5db6e7c
[poolifier.git] / src / pools / selection-strategies / less-busy-worker-choice-strategy.ts
1 import type { IWorker } from '../worker'
2 import { AbstractWorkerChoiceStrategy } from './abstract-worker-choice-strategy'
3 import type {
4 IWorkerChoiceStrategy,
5 RequiredStatistics
6 } from './selection-strategies-types'
7
8 /**
9 * Selects the less busy worker.
10 *
11 * @typeParam Worker - Type of worker which manages the strategy.
12 * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
13 * @typeParam Response - Type of response of execution. This can only be serializable data.
14 */
15 export class LessBusyWorkerChoiceStrategy<
16 Worker extends IWorker,
17 Data = unknown,
18 Response = unknown
19 >
20 extends AbstractWorkerChoiceStrategy<Worker, Data, Response>
21 implements IWorkerChoiceStrategy {
22 /** @inheritDoc */
23 public readonly requiredStatistics: RequiredStatistics = {
24 runTime: true,
25 avgRunTime: false,
26 medRunTime: false
27 }
28
29 /** @inheritDoc */
30 public reset (): boolean {
31 return true
32 }
33
34 /** @inheritDoc */
35 public choose (): number {
36 const freeWorkerNodeKey = this.pool.findFreeWorkerNodeKey()
37 if (freeWorkerNodeKey !== -1) {
38 return freeWorkerNodeKey
39 }
40 let minRunTime = Infinity
41 let lessBusyWorkerNodeKey!: number
42 for (const [index, workerNode] of this.pool.workerNodes.entries()) {
43 const workerRunTime = workerNode.tasksUsage.runTime
44 if (workerRunTime === 0) {
45 return index
46 } else if (workerRunTime < minRunTime) {
47 minRunTime = workerRunTime
48 lessBusyWorkerNodeKey = index
49 }
50 }
51 return lessBusyWorkerNodeKey
52 }
53
54 /** @inheritDoc */
55 public remove (workerNodeKey: number): boolean {
56 return true
57 }
58 }