You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jan 19, 2021. It is now read-only.
Copy file name to clipboardExpand all lines: src/prioritizedTaskExecutor.ts
+31-11
Original file line number
Diff line number
Diff line change
@@ -1,3 +1,5 @@
1
+
importSemaphorefrom'semaphore-async-await'
2
+
1
3
interfaceTask{
2
4
priority: number
3
5
fn: Function
@@ -10,6 +12,8 @@ export class PrioritizedTaskExecutor {
10
12
privatecurrentPoolSize: number
11
13
/** The task queue */
12
14
privatequeue: Task[]
15
+
/** The Lock */
16
+
privatelock: Semaphore
13
17
14
18
/**
15
19
* Executes tasks up to maxPoolSize at a time, other items are put in a priority queue.
@@ -21,6 +25,7 @@ export class PrioritizedTaskExecutor {
21
25
this.maxPoolSize=maxPoolSize
22
26
this.currentPoolSize=0
23
27
this.queue=[]
28
+
this.lock=newSemaphore(1)
24
29
}
25
30
26
31
/**
@@ -29,17 +34,22 @@ export class PrioritizedTaskExecutor {
29
34
* @param priority The priority of the task
30
35
* @param fn The function that accepts the callback, which must be called upon the task completion.
31
36
*/
32
-
execute(priority: number,fn: Function){
33
-
if(this.currentPoolSize<this.maxPoolSize){
34
-
this.currentPoolSize++
35
-
fn(()=>{
36
-
this.currentPoolSize--
37
-
if(this.queue.length>0){
38
-
constitem=this.queue.shift()
39
-
this.execute(item!.priority,item!.fn)
37
+
asyncexecute(priority: number,fn: Function){
38
+
letself=this
39
+
functionrunTask(){
40
+
self.currentPoolSize++
41
+
fn(async()=>{
42
+
self.currentPoolSize--
43
+
if(self.queue.length>0){
44
+
constitem=self.queue.shift()
45
+
awaitself.execute(item!.priority,item!.fn)
40
46
}
41
47
})
48
+
}
49
+
if(this.currentPoolSize<this.maxPoolSize){
50
+
runTask()
42
51
}else{
52
+
awaitthis.lock.wait()
43
53
if(this.queue.length==0){
44
54
this.queue.push({ priority, fn })
45
55
}else{
@@ -50,15 +60,24 @@ export class PrioritizedTaskExecutor {
50
60
returnMath.floor(left+(right-left)/2)
51
61
}
52
62
while(true){
63
+
// note that there is a special case: it could be that during sorting, a Task is finished (reducing currentPoolSize by 1), but this Task was not yet inserted
64
+
// therefore, if we want to insert the item we explicitly check that we indeed should Queue it, if not, we execute it and do not insert it.
53
65
letindex=mid()
54
66
letvalue=this.queue[index].priority
55
-
console.log(left,right,index,value)
56
67
if(value==priority){
57
-
this.queue.splice(index,0,{ priority, fn })
68
+
if(this.currentPoolSize<this.maxPoolSize){
69
+
runTask()
70
+
}else{
71
+
this.queue.splice(index,0,{ priority, fn })
72
+
}
58
73
break
59
74
}
60
75
if(left==right){
61
-
this.queue.splice(left,0,{ priority, fn })
76
+
if(this.currentPoolSize<this.maxPoolSize){
77
+
runTask()
78
+
}else{
79
+
this.queue.splice(left,0,{ priority, fn })
80
+
}
62
81
break
63
82
}
64
83
@@ -69,6 +88,7 @@ export class PrioritizedTaskExecutor {
0 commit comments