forked from VSCodeVim/Vim
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtaskQueue.ts
More file actions
92 lines (80 loc) · 2.16 KB
/
taskQueue.ts
File metadata and controls
92 lines (80 loc) · 2.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import * as _ from 'lodash';
interface IEnqueuedTask {
promise: () => Promise<void>;
isRunning: boolean;
queue: string;
isHighPriority: boolean;
}
class TaskQueue {
private _taskQueue: {
[key: string]: {
tasks: IEnqueuedTask[];
};
} = {};
private isRunning(queueName: string): boolean {
return (
this._taskQueue[queueName] &&
_.filter(this._taskQueue[queueName].tasks, x => x.isRunning).length > 0
);
}
private numHighPriority(queueName: string): number {
if (!this._taskQueue[queueName]) {
return 0;
}
return _.filter(this._taskQueue[queueName].tasks, x => x.isHighPriority).length;
}
private async runTasks(queueName: string): Promise<void> {
while (this._taskQueue[queueName].tasks.length > 0) {
let task: IEnqueuedTask = this._taskQueue[queueName].tasks[0];
try {
task.isRunning = true;
await task.promise();
task.isRunning = false;
} catch (e) {
console.error(e);
} finally {
this.dequeueTask(task);
}
}
}
/**
* Dequeues a task from the task queue.
*
* Note: If the task is already running, the semantics of
* promises don't allow you to stop it.
*/
private dequeueTask(task: IEnqueuedTask): void {
_.remove(this._taskQueue[task.queue].tasks, t => t === task);
}
/**
* Adds a task to the task queue.
*/
public enqueueTask(
action: () => Promise<void>,
queueName: string = 'default',
isHighPriority: boolean = false
): void {
let task: IEnqueuedTask = {
promise: action,
queue: queueName,
isHighPriority: isHighPriority,
isRunning: false,
};
if (!this._taskQueue[queueName]) {
this._taskQueue[queueName] = {
tasks: [],
};
}
if (isHighPriority) {
// Insert task as the last high priotity task.
const numHighPriority = this.numHighPriority(queueName);
this._taskQueue[queueName].tasks.splice(numHighPriority, 0, task);
} else {
this._taskQueue[queueName].tasks.push(task);
}
if (!this.isRunning(queueName)) {
this.runTasks(queueName);
}
}
}
export let taskQueue = new TaskQueue();