Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 33x 33x 25x 25x 25x 25x 25x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7x 7x 1x 1x | /*
* Copyright 2021 Harness Inc. All rights reserved.
* Use of this source code is governed by the PolyForm Shield 1.0.0 license
* that can be found in the licenses directory at the root of this repository, also available at
* https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt.
*/
export type PromiseThunk = (signal: AbortSignal) => Promise<unknown>
import { v4 as uuid } from 'uuid'
export class PQueue {
private queue: Array<() => void> = []
private runningCount = 0
private concurrency = Infinity
private controllerMap = new Map<string, AbortController>()
constructor(concurrency?: number) {
Iif (typeof concurrency === 'number' && concurrency >= 1) {
this.concurrency = concurrency
}
}
add(fn: PromiseThunk): Promise<unknown> {
return new Promise((resolve, reject) => {
const run = (): void => {
this.runningCount++
const uid = uuid()
const controller = new AbortController()
this.controllerMap.set(uid, controller)
fn(controller.signal).then(
(value: unknown) => {
resolve(value)
this.controllerMap.delete(uid)
this.runningCount--
this.next()
},
(err: Error) => {
this.controllerMap.delete(uid)
if (err instanceof DOMException && err.name === 'AbortError') {
// do nothing
} else {
reject(err)
}
this.runningCount--
this.next()
}
)
}
Eif (this.runningCount < this.concurrency) {
run()
} else {
this.queue.push(run)
}
})
}
cancel(): void {
this.controllerMap.forEach(controller => {
controller.abort()
})
this.controllerMap.clear()
}
private next(): void {
Iif (this.runningCount >= this.concurrency) {
return
}
Iif (this.queue.length > 0) {
const task = this.queue.shift()
if (task) {
task()
}
}
}
}
|