File size: 857 Bytes
82b44e7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/** Bound parallel DB reads so large rosters do not create unbounded fan-out. */
export async function readBatches<T, R>(
  items: readonly T[],
  load: (batch: T[]) => PromiseLike<readonly R[]>,
  batchSize = 100,
  concurrency = 4,
): Promise<R[]> {
  if (!Number.isInteger(batchSize) || batchSize < 1 ||
      !Number.isInteger(concurrency) || concurrency < 1) throw new Error("Invalid batch configuration");
  const output: R[] = [];
  for (let offset = 0; offset < items.length; offset += batchSize * concurrency) {
    const group: PromiseLike<readonly R[]>[] = [];
    for (let cursor = offset; cursor < Math.min(items.length, offset + batchSize * concurrency); cursor += batchSize) {
      group.push(load(items.slice(cursor, cursor + batchSize)));
    }
    for (const rows of await Promise.all(group)) output.push(...rows);
  }
  return output;
}