-
Notifications
You must be signed in to change notification settings - Fork 16
/
batch.ts
37 lines (33 loc) · 1015 Bytes
/
batch.ts
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
// TODO(#323): move to ../iterator
import logger from '../../entities/Development/logger'
type BatchCallback<T> = (batch: T[]) => Promise<any>
export default function batch<T>(callback: BatchCallback<T>, limit = 100) {
let queue: { item: T; callback: () => void }[] = []
let exec: null | Promise<any> = null
function run() {
if (queue.length > 0 && exec === null) {
exec = Promise.resolve().then(async () => {
const current = queue.slice(0, limit)
queue = queue.slice(limit)
try {
await callback(current.map((value) => value.item))
current.map((value) => value.callback())
exec = null
run()
} catch (err) {
logger.error(`Error processing batch: ${err.message}`, err)
exec = null
run()
}
})
}
}
return async function batcher(item: T) {
return new Promise<void>((callback) => {
queue.push({ item, callback })
if (!exec) {
run()
}
})
}
}