1 | interface Task {
|
2 | priority: number
|
3 | fn: Function
|
4 | }
|
5 |
|
6 | export class PrioritizedTaskExecutor {
|
7 | /** The maximum size of the pool */
|
8 | private maxPoolSize: number
|
9 | /** The current size of the pool */
|
10 | private currentPoolSize: number
|
11 | /** The task queue */
|
12 | private queue: Task[]
|
13 |
|
14 | /**
|
15 | * Executes tasks up to maxPoolSize at a time, other items are put in a priority queue.
|
16 | * @class PrioritizedTaskExecutor
|
17 | * @private
|
18 | * @param maxPoolSize The maximum size of the pool
|
19 | */
|
20 | constructor(maxPoolSize: number) {
|
21 | this.maxPoolSize = maxPoolSize
|
22 | this.currentPoolSize = 0
|
23 | this.queue = []
|
24 | }
|
25 |
|
26 | /**
|
27 | * Executes the task or queues it if no spots are available.
|
28 | * When a task is added, check if there are spots left in the pool.
|
29 | * If a spot is available, claim that spot and give back the spot once the asynchronous task has been resolved.
|
30 | * When no spots are available, add the task to the task queue. The task will be executed at some point when another task has been resolved.
|
31 | * @private
|
32 | * @param priority The priority of the task
|
33 | * @param fn The function that accepts the callback, which must be called upon the task completion.
|
34 | */
|
35 | executeOrQueue(priority: number, fn: Function) {
|
36 | if (this.currentPoolSize < this.maxPoolSize) {
|
37 | this.currentPoolSize++
|
38 | fn(() => {
|
39 | this.currentPoolSize--
|
40 | if (this.queue.length > 0) {
|
41 | this.queue.sort((a, b) => b.priority - a.priority)
|
42 | const item = this.queue.shift()
|
43 | this.executeOrQueue(item!.priority, item!.fn)
|
44 | }
|
45 | })
|
46 | } else {
|
47 | this.queue.push({ priority, fn })
|
48 | }
|
49 | }
|
50 |
|
51 | /**
|
52 | * Checks if the taskExecutor is finished.
|
53 | * @private
|
54 | * @returns Returns `true` if the taskExecutor is finished, otherwise returns `false`.
|
55 | */
|
56 | finished(): boolean {
|
57 | return this.currentPoolSize === 0
|
58 | }
|
59 | }
|