-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTaskManager.mjs
105 lines (88 loc) · 2.9 KB
/
TaskManager.mjs
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
93
94
95
96
97
98
99
100
101
102
103
104
105
export default class TaskManager {
#taskList; // Given task list
#concurrencyMax; // Max concurrent tasks to run
#currentConcurrency = 0; // current no of concurrent tasks that are running
#tasksRunningCounter = 0; // counter of the tasks that started
#totalCompleted = 0; // counter of tasks that are successfully completed
constructor(taskList = [], concurrencyMax = 4) {
this.#taskList = taskList;
this.#concurrencyMax = concurrencyMax;
}
updateConcurrencyMax(newConcurrencyMax) {
this.#concurrencyMax = newConcurrencyMax;
}
async start() {
console.log("[init] Concurrency Algo Testing...");
console.log("[init] Tasks to process: ", this.#taskList.length);
console.log("[init] Task list: " + this.#taskList);
console.log("[init] Maximum Concurrency: ", this.#concurrencyMax, "\n");
await this.#processTasks();
}
async #processTasks() {
// Kick off the initial tasks limitting to current concurrency maximum.
await Promise.all(
this.#taskList
.slice(this.#tasksRunningCounter, this.#concurrencyMax)
.map((task) => {
return this.#processTask(task);
})
);
}
async #processTask(taskName) {
// track progress
this.#currentConcurrency++;
this.#tasksRunningCounter++;
console.log(
`Concurrency ${this.#currentConcurrency} of ${this.#concurrencyMax}`
);
console.log(
`Task count ${this.#tasksRunningCounter} of ${this.#taskList.length}`
);
// do the task work
await this.#doTask(taskName);
// a task was complted
this.#totalCompleted++;
// decrease counter to allow for next concurrent task
this.#currentConcurrency--;
// if this was the last task completed, show success message and return
if (this.#allTaskCompleted()) {
console.log("All tasks are successfully completed.");
return;
}
// else process next tasks
else {
this.#processNextTasks();
}
}
#allTaskCompleted() {
return this.#totalCompleted == this.#taskList.length;
}
async #processNextTasks() {
// fill the concurrency with the remaining tasks
while (this.#concurrencyNotFull() && this.tasksAreRemaining()) {
this.#processTask(this.#taskList[this.#tasksRunningCounter]);
}
}
#concurrencyNotFull() {
return this.#currentConcurrency < this.#concurrencyMax;
}
tasksAreRemaining() {
return this.#tasksRunningCounter < this.#taskList.length;
}
#doTask(taskName) {
console.log("\x1b[36m", "[TASK] STARTED: " + taskName, "\x1b[0m");
const begin = Date.now();
return new Promise(function (resolve, reject) {
setTimeout(function () {
const end = Date.now();
const timeSpent = end - begin + "ms";
console.log(
"\x1b[36m",
"[TASK] FINISHED: " + taskName + " in " + timeSpent,
"\x1b[0m"
);
resolve(true);
}, Math.random() * 200);
});
}
}