mirror of git3://git3.w3q/git3-cli
parent
4111f842d6
commit
e1b38802b8
@ -0,0 +1,77 @@
|
||||
export class QueueTask {
|
||||
maxRetry: number = 0
|
||||
queueInterval: number = 0
|
||||
maxPending: number = 0
|
||||
retryInterval: number = 0
|
||||
|
||||
lastTaskScheduled: number = 0
|
||||
pending: number = 0
|
||||
|
||||
checkPointWait!: Promise<void>
|
||||
checkPointResolve: any
|
||||
|
||||
constructor({
|
||||
maxRetry = 10,
|
||||
queueInterval = 0,
|
||||
maxPending = 0,
|
||||
retryInterval = 0,
|
||||
}) {
|
||||
this.maxRetry = maxRetry
|
||||
this.queueInterval = queueInterval
|
||||
this.maxPending = maxPending
|
||||
this.retryInterval = retryInterval
|
||||
this.refreshCheckPoint()
|
||||
}
|
||||
|
||||
async refreshCheckPoint() {
|
||||
this.checkPointWait = new Promise((resolve) => {
|
||||
this.checkPointResolve = resolve
|
||||
})
|
||||
}
|
||||
|
||||
async tickThread() {
|
||||
return new Promise(async (resolve) => {
|
||||
let now = Date.now().valueOf()
|
||||
if (this.maxPending > 0) {
|
||||
while (this.pending >= this.maxPending) {
|
||||
await this.checkPointWait
|
||||
this.checkPointWait = new Promise((resolve) => {
|
||||
this.checkPointResolve = resolve
|
||||
})
|
||||
}
|
||||
}
|
||||
if (now - this.lastTaskScheduled < this.queueInterval) {
|
||||
let delta = this.queueInterval - (now - this.lastTaskScheduled)
|
||||
setTimeout(() => {
|
||||
resolve(true)
|
||||
}, delta)
|
||||
this.lastTaskScheduled = delta
|
||||
return
|
||||
} else {
|
||||
this.lastTaskScheduled = now
|
||||
resolve(true)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async run(func: Function, retry: number = this.maxRetry): Promise<any> {
|
||||
let lastError
|
||||
for (let i = 0; i < retry; i++) {
|
||||
await this.tickThread()
|
||||
this.pending++
|
||||
try {
|
||||
let res = await func()
|
||||
this.pending--
|
||||
this.checkPointResolve(true)
|
||||
return res
|
||||
} catch (err: any) {
|
||||
lastError = err
|
||||
this.pending--
|
||||
this.checkPointResolve(true)
|
||||
new Promise((r) => setTimeout(r, this.retryInterval))
|
||||
}
|
||||
}
|
||||
if (lastError) throw lastError
|
||||
}
|
||||
}
|
Loading…
Reference in new issue