From 6fac56d2c99acf1037fd65abdacfc27b776509a8 Mon Sep 17 00:00:00 2001 From: Marshall Polaris Date: Thu, 9 Jun 2022 15:13:06 -0700 Subject: [PATCH] Make feed updating do much less work (#455) --- functions/src/get-feed-data.ts | 5 ++-- functions/src/update-feed.ts | 44 +++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/functions/src/get-feed-data.ts b/functions/src/get-feed-data.ts index 75782fed..dc45f563 100644 --- a/functions/src/get-feed-data.ts +++ b/functions/src/get-feed-data.ts @@ -42,8 +42,8 @@ export async function getTaggedContracts(tag: string) { return taggedContracts.filter((c) => (c.closeTime ?? Infinity) > Date.now()) } -export async function getRecentBetsAndComments(contract: Contract) { - const contractDoc = firestore.collection('contracts').doc(contract.id) +export async function getRecentBetsAndComments(contractId: string) { + const contractDoc = firestore.collection('contracts').doc(contractId) const [recentBets, recentComments] = await Promise.all([ getValues( @@ -64,7 +64,6 @@ export async function getRecentBetsAndComments(contract: Contract) { ]) return { - contract, recentBets, recentComments, } diff --git a/functions/src/update-feed.ts b/functions/src/update-feed.ts index 03b1666c..f19fda92 100644 --- a/functions/src/update-feed.ts +++ b/functions/src/update-feed.ts @@ -1,6 +1,6 @@ import * as functions from 'firebase-functions' import * as admin from 'firebase-admin' -import { shuffle, sortBy } from 'lodash' +import { flatten, shuffle, sortBy, uniq, zip, zipObject } from 'lodash' import { getValue, getValues } from './utils' import { Contract } from '../../common/contract' @@ -67,15 +67,16 @@ export const updateFeedBatch = functions.https.onCall( async (data: { users: User[] }) => { const { users } = data const contracts = await getFeedContracts() - + const feeds = await getNewFeeds(users, contracts) await Promise.all( - users.map(async (user) => { - const feed = await computeFeed(user, contracts) - await getUserCacheCollection(user).doc('feed').set({ feed }) - }) + zip(users, feeds).map(([user, feed]) => + /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */ + getUserCacheCollection(user!).doc('feed').set({ feed }) + ) ) } ) + export const updateCategoryFeed = functions.https.onCall( async (data: { category: string }) => { const { category } = data @@ -96,16 +97,28 @@ export const updateCategoryFeedBatch = functions.https.onCall( async (data: { users: User[]; category: string }) => { const { users, category } = data const contracts = await getTaggedContracts(category) - + const feeds = await getNewFeeds(users, contracts) await Promise.all( - users.map(async (user) => { - const feed = await computeFeed(user, contracts) - await getUserCacheCollection(user).doc(`feed-${category}`).set({ feed }) - }) + zip(users, feeds).map(([user, feed]) => + /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */ + getUserCacheCollection(user!).doc(`feed-${category}`).set({ feed }) + ) ) } ) +const getNewFeeds = async (users: User[], contracts: Contract[]) => { + const feeds = await Promise.all(users.map((u) => computeFeed(u, contracts))) + const contractIds = uniq(flatten(feeds).map((c) => c.id)) + const data = await Promise.all(contractIds.map(getRecentBetsAndComments)) + const dataByContractId = zipObject(contractIds, data) + return feeds.map((feed) => + feed.map((contract) => { + return { contract, ...dataByContractId[contract.id] } + }) + ) +} + const getUserCacheCollection = (user: User) => firestore.collection(`private-users/${user.id}/cache`) @@ -135,14 +148,7 @@ export const computeFeed = async (user: User, contracts: Contract[]) => { // console.log(sortedContracts.map(([c, score]) => c.question + ': ' + score)) - const feedContracts = sortedContracts - .slice(0, MAX_FEED_CONTRACTS) - .map(([c]) => c) - - const feed = await Promise.all( - feedContracts.map((contract) => getRecentBetsAndComments(contract)) - ) - return feed + return sortedContracts.slice(0, MAX_FEED_CONTRACTS).map(([c]) => c) } function scoreContract(