1 import type { AbstractPoolWorker
} from
'../abstract-pool-worker'
2 import { AbstractWorkerChoiceStrategy
} from
'./abstract-worker-choice-strategy'
5 * Worker virtual task timestamp.
7 type WorkerVirtualTaskTimestamp
= {
13 * Selects the next worker with a fair share scheduling algorithm.
14 * Loosely modeled after the fair queueing algorithm: https://en.wikipedia.org/wiki/Fair_queuing.
16 * @template Worker Type of worker which manages the strategy.
17 * @template Data Type of data sent to the worker. This can only be serializable data.
18 * @template Response Type of response of execution. This can only be serializable data.
20 export class FairShareWorkerChoiceStrategy
<
21 Worker
extends AbstractPoolWorker
,
24 > extends AbstractWorkerChoiceStrategy
<Worker
, Data
, Response
> {
26 * Worker last virtual task execution timestamp.
28 private workerLastVirtualTaskTimestamp
: Map
<
30 WorkerVirtualTaskTimestamp
31 > = new Map
<Worker
, WorkerVirtualTaskTimestamp
>()
34 public choose (): Worker
{
35 this.updateWorkerLastVirtualTaskTimestamp()
36 let minWorkerVirtualTaskEndTimestamp
= Infinity
37 let chosenWorker
!: Worker
38 for (const worker
of this.pool
.workers
) {
39 const workerLastVirtualTaskEndTimestamp
=
40 this.workerLastVirtualTaskTimestamp
.get(worker
)?.end
?? 0
42 workerLastVirtualTaskEndTimestamp
< minWorkerVirtualTaskEndTimestamp
44 minWorkerVirtualTaskEndTimestamp
= workerLastVirtualTaskEndTimestamp
52 * Compute workers last virtual task timestamp.
54 private updateWorkerLastVirtualTaskTimestamp () {
55 for (const worker
of this.pool
.workers
) {
56 const workerVirtualTaskStartTimestamp
= Math.max(
58 this.workerLastVirtualTaskTimestamp
.get(worker
)?.end
?? 0
60 const workerVirtualTaskEndTimestamp
=
61 workerVirtualTaskStartTimestamp
+
62 (this.pool
.getWorkerAverageTasksRunTime(worker
) ?? 0)
63 this.workerLastVirtualTaskTimestamp
.set(worker
, {
64 start
: workerVirtualTaskStartTimestamp
,
65 end
: workerVirtualTaskEndTimestamp