UNPKG

1.86 kBPlain TextView Raw
1interface Task {
2 priority: number
3 fn: Function
4}
5
6export 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}