diff --git a/common/util/promise.ts b/common/util/promise.ts new file mode 100644 index 00000000..33db339c --- /dev/null +++ b/common/util/promise.ts @@ -0,0 +1,18 @@ +export const batchedWaitAll = async ( + createPromises: (() => Promise)[], + batchSize = 10 +) => { + const numBatches = Math.ceil(createPromises.length / batchSize) + const result: T[] = [] + for (let batchIndex = 0; batchIndex < numBatches; batchIndex++) { + const from = batchIndex * batchSize + const to = from + batchSize + + const promises = createPromises.slice(from, to).map((f) => f()) + + const batch = await Promise.all(promises) + result.push(...batch) + } + + return result +} diff --git a/functions/src/update-contract-metrics.ts b/functions/src/update-contract-metrics.ts index 3646e7ad..d203ee99 100644 --- a/functions/src/update-contract-metrics.ts +++ b/functions/src/update-contract-metrics.ts @@ -5,6 +5,7 @@ import * as _ from 'lodash' import { getValues } from './utils' import { Contract } from '../../common/contract' import { Bet } from '../../common/bet' +import { batchedWaitAll } from '../../common/util/promise' const firestore = admin.firestore() @@ -17,8 +18,8 @@ export const updateContractMetrics = functions.pubsub firestore.collection('contracts') ) - await Promise.all( - contracts.map(async (contract) => { + await batchedWaitAll( + contracts.map((contract) => async () => { const volume24Hours = await computeVolumeFrom(contract, oneDay) const volume7Days = await computeVolumeFrom(contract, oneDay * 7) diff --git a/functions/src/update-user-metrics.ts b/functions/src/update-user-metrics.ts index d1d13727..358dd936 100644 --- a/functions/src/update-user-metrics.ts +++ b/functions/src/update-user-metrics.ts @@ -7,6 +7,7 @@ import { Contract } from '../../common/contract' import { Bet } from '../../common/bet' import { User } from '../../common/user' import { calculatePayout } from '../../common/calculate' +import { batchedWaitAll } from '../../common/util/promise' const firestore = admin.firestore() @@ -22,8 +23,8 @@ export const updateUserMetrics = functions.pubsub contracts.map((contract) => [contract.id, contract]) ) - await Promise.all( - users.map(async (user) => { + await batchedWaitAll( + users.map((user) => async () => { const [investmentValue, creatorVolume] = await Promise.all([ computeInvestmentValue(user, contractsDict), computeTotalPool(user, contractsDict),