mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-03-30 04:23:03 -04:00
* Test * Add pretty formatting * Fix Tests * Fix Tests * Fix Tests * Fix * Add pretty formatting fix * Fix * Test * Fix tests * Clean typeckech * Add prettier check * Fix api tsconfig * Fix api tsconfig * Fix tsconfig * Fix * Fix * Prettier
81 lines
2.1 KiB
TypeScript
81 lines
2.1 KiB
TypeScript
export type RetryPolicy = {
|
|
initialBackoffSec: number
|
|
retries: number
|
|
}
|
|
|
|
export const delay = (ms: number) => {
|
|
return new Promise<void>((resolve) => setTimeout(() => resolve(), ms))
|
|
}
|
|
|
|
export async function withRetries<T>(q: PromiseLike<T>, policy?: RetryPolicy) {
|
|
let err: Error | undefined
|
|
let delaySec = policy?.initialBackoffSec ?? 5
|
|
const maxRetries = policy?.retries ?? 5
|
|
for (let i = 0; i < maxRetries; i++) {
|
|
try {
|
|
return await q
|
|
} catch (e) {
|
|
err = e as Error
|
|
if (i < maxRetries) {
|
|
console.debug(`Error: ${err.message} - Retrying in ${delaySec}s.`)
|
|
await delay(delaySec * 1000)
|
|
delaySec *= 2
|
|
}
|
|
}
|
|
}
|
|
throw err
|
|
}
|
|
|
|
export const mapAsyncChunked = async <T, U>(
|
|
items: T[],
|
|
f: (item: T, index: number) => Promise<U>,
|
|
chunkSize = 100,
|
|
) => {
|
|
const results: U[] = []
|
|
|
|
for (let i = 0; i < items.length; i += chunkSize) {
|
|
const chunk = items.slice(i, i + chunkSize)
|
|
const chunkResults = await Promise.all(chunk.map((item, index) => f(item, i + index)))
|
|
results.push(...chunkResults)
|
|
}
|
|
|
|
return results
|
|
}
|
|
|
|
export const mapAsync = <T, U>(
|
|
items: T[],
|
|
f: (item: T, index: number) => Promise<U>,
|
|
maxConcurrentRequests = 100,
|
|
) => {
|
|
let index = 0
|
|
let currRequests = 0
|
|
const results: U[] = []
|
|
|
|
// The following is a hack to fix a Node bug where the process exits before
|
|
// the promise is resolved.
|
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
const intervalId = setInterval(() => {}, 10000)
|
|
|
|
return new Promise((resolve: (results: U[]) => void, reject) => {
|
|
const doWork = () => {
|
|
while (index < items.length && currRequests < maxConcurrentRequests) {
|
|
const itemIndex = index
|
|
f(items[itemIndex], itemIndex)
|
|
.then((data) => {
|
|
results[itemIndex] = data
|
|
currRequests--
|
|
if (index === items.length && currRequests === 0) resolve(results)
|
|
else doWork()
|
|
})
|
|
.catch(reject)
|
|
|
|
index++
|
|
currRequests++
|
|
}
|
|
}
|
|
|
|
if (items.length === 0) resolve([])
|
|
else doWork()
|
|
}).finally(() => clearInterval(intervalId))
|
|
}
|