-
Notifications
You must be signed in to change notification settings - Fork 96
Expand file tree
/
Copy pathbatch-runner.ts
More file actions
49 lines (41 loc) · 1.31 KB
/
Copy pathbatch-runner.ts
File metadata and controls
49 lines (41 loc) · 1.31 KB
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
export type BatchResult<R> =
| { status: 'fulfilled'; value: R }
| { status: 'rejected'; reason: any }
| { status: 'skipped_circuit_open' };
export async function runWithConcurrency<T, R>(
items: T[],
limit: number,
worker: (item: T) => Promise<R>,
circuitBreakerCheck?: () => boolean
): Promise<BatchResult<R>[]> {
const results: BatchResult<R>[] = new Array(items.length);
let currentIndex = 0;
let isCircuitOpen = false;
async function processNext(): Promise<void> {
while (true) {
if (currentIndex >= items.length) {
return;
}
const index = currentIndex++;
const item = items[index];
if (isCircuitOpen || (circuitBreakerCheck && circuitBreakerCheck())) {
isCircuitOpen = true; // Mark as open for the rest of the batch
results[index] = { status: 'skipped_circuit_open' };
continue;
}
try {
const value = await worker(item);
results[index] = { status: 'fulfilled', value };
} catch (error) {
results[index] = { status: 'rejected', reason: error };
}
}
}
const workers: Promise<void>[] = [];
const actualLimit = Math.min(limit, items.length);
for (let i = 0; i < actualLimit; i++) {
workers.push(processNext());
}
await Promise.all(workers);
return results;
}