Optimize updateContractMetrics
(#476)
* Don't query bets repeatedly * Don't read entire database of contracts for no reason * Fix lint
This commit is contained in:
parent
3a6960c71b
commit
d8dc91d4b7
|
@ -1,9 +1,8 @@
|
||||||
import * as functions from 'firebase-functions'
|
import * as functions from 'firebase-functions'
|
||||||
import * as admin from 'firebase-admin'
|
import * as admin from 'firebase-admin'
|
||||||
import { sumBy } from 'lodash'
|
import { max, sumBy } from 'lodash'
|
||||||
|
|
||||||
import { getValues } from './utils'
|
import { getValues } from './utils'
|
||||||
import { Contract } from '../../common/contract'
|
|
||||||
import { Bet } from '../../common/bet'
|
import { Bet } from '../../common/bet'
|
||||||
import { batchedWaitAll } from '../../common/util/promise'
|
import { batchedWaitAll } from '../../common/util/promise'
|
||||||
|
|
||||||
|
@ -14,17 +13,14 @@ const oneDay = 1000 * 60 * 60 * 24
|
||||||
export const updateContractMetrics = functions.pubsub
|
export const updateContractMetrics = functions.pubsub
|
||||||
.schedule('every 15 minutes')
|
.schedule('every 15 minutes')
|
||||||
.onRun(async () => {
|
.onRun(async () => {
|
||||||
const contracts = await getValues<Contract>(
|
const contractDocs = await firestore.collection('contracts').listDocuments()
|
||||||
firestore.collection('contracts')
|
|
||||||
)
|
|
||||||
|
|
||||||
await batchedWaitAll(
|
await batchedWaitAll(
|
||||||
contracts.map((contract) => async () => {
|
contractDocs.map((doc) => async () => {
|
||||||
const volume24Hours = await computeVolumeFrom(contract, oneDay)
|
const [volume24Hours, volume7Days] = await computeVolumes(doc.id, [
|
||||||
const volume7Days = await computeVolumeFrom(contract, oneDay * 7)
|
oneDay,
|
||||||
|
oneDay * 7,
|
||||||
const contractRef = firestore.doc(`contracts/${contract.id}`)
|
])
|
||||||
return contractRef.update({
|
return doc.update({
|
||||||
volume24Hours,
|
volume24Hours,
|
||||||
volume7Days,
|
volume7Days,
|
||||||
})
|
})
|
||||||
|
@ -32,12 +28,17 @@ export const updateContractMetrics = functions.pubsub
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const computeVolumeFrom = async (contract: Contract, timeAgoMs: number) => {
|
const computeVolumes = async (contractId: string, durationsMs: number[]) => {
|
||||||
const bets = await getValues<Bet>(
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
const longestDurationMs = max(durationsMs)!
|
||||||
|
const allBets = await getValues<Bet>(
|
||||||
firestore
|
firestore
|
||||||
.collection(`contracts/${contract.id}/bets`)
|
.collection(`contracts/${contractId}/bets`)
|
||||||
.where('createdTime', '>', Date.now() - timeAgoMs)
|
.where('createdTime', '>', Date.now() - longestDurationMs)
|
||||||
)
|
)
|
||||||
|
return durationsMs.map((duration) => {
|
||||||
return sumBy(bets, (bet) => (bet.isRedemption ? 0 : Math.abs(bet.amount)))
|
const cutoff = Date.now() - duration
|
||||||
|
const bets = allBets.filter((b) => b.createdTime > cutoff)
|
||||||
|
return sumBy(bets, (bet) => (bet.isRedemption ? 0 : Math.abs(bet.amount)))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user