Skip to content

Commit

Permalink
fix: Optimize processRecurrence (#9670)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dschoordsch committed Apr 30, 2024
1 parent 56a54b3 commit eb6e608
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 27 deletions.
41 changes: 19 additions & 22 deletions packages/server/dataloader/customLoaderMakers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import getRedis from '../utils/getRedis'
import isUserVerified from '../utils/isUserVerified'
import NullableDataLoader from './NullableDataLoader'
import RootDataLoader from './RootDataLoader'
import normalizeArrayResults from './normalizeArrayResults'
import normalizeResults from './normalizeResults'

export interface MeetingSettingsKey {
Expand Down Expand Up @@ -611,17 +612,13 @@ export const activeMeetingsByMeetingSeriesId = (parent: RootDataLoader) => {
return new DataLoader<number, AnyMeeting[], string>(
async (keys) => {
const r = await getRethink()
const res = await Promise.all(
keys.map((key) => {
return r
.table('NewMeeting')
.getAll(key, {index: 'meetingSeriesId'})
.filter({endedAt: null}, {default: true})
.orderBy(r.asc('createdAt'))
.run()
})
)
return res
const res = await r
.table('NewMeeting')
.getAll(r.args(keys), {index: 'meetingSeriesId'})
.filter({endedAt: null}, {default: true})
.orderBy(r.asc('createdAt'))
.run()
return normalizeArrayResults(keys, res, 'meetingSeriesId')
},
{
...parent.dataLoaderOptions
Expand All @@ -633,18 +630,18 @@ export const lastMeetingByMeetingSeriesId = (parent: RootDataLoader) => {
return new DataLoader<number, AnyMeeting | null, string>(
async (keys) => {
const r = await getRethink()
const res = await Promise.all(
keys.map((key) => {
return r
.table('NewMeeting')
.getAll(key, {index: 'meetingSeriesId'})
.orderBy(r.desc('createdAt'))
.nth(0)
.default(null)
.run()
})
const res = await (
r
.table('NewMeeting')
.getAll(r.args(keys), {index: 'meetingSeriesId'})
.group('meetingSeriesId') as RDatum
)
return res
.orderBy(r.desc('createdAt'))
.nth(0)
.default(null)
.ungroup()('reduction')
.run()
return normalizeResults(keys, res as AnyMeeting[], 'meetingSeriesId')
},
{
...parent.dataLoaderOptions
Expand Down
23 changes: 23 additions & 0 deletions packages/server/dataloader/normalizeArrayResults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Normalize results with a one to many mapping for the keys, so the key is usually a foreign key
*/
export const normalizeArrayResults = <KeyT extends string | number, T extends {[key: string]: any}>(
keys: Readonly<KeyT[]>,
results: T[],
key: keyof T
) => {
const map = {} as Record<KeyT, T[]>
results.forEach((result: T) => {
if (!map[result[key]]) {
map[result[key]] = [] as T[]
}
map[result[key]].push(result)
})
const mappedResults = [] as T[][]
keys.forEach((key) => {
mappedResults.push(map[key])
})
return mappedResults
}

export default normalizeArrayResults
23 changes: 18 additions & 5 deletions packages/server/graphql/private/mutations/processRecurrence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {getActiveMeetingSeries} from '../../../postgres/queries/getActiveMeeting
import {MeetingSeries} from '../../../postgres/types/MeetingSeries'
import {analytics} from '../../../utils/analytics/analytics'
import publish, {SubOptions} from '../../../utils/publish'
import sendToSentry from '../../../utils/sendToSentry'
import standardError from '../../../utils/standardError'
import {DataLoaderWorker} from '../../graphql'
import {createMeetingSeriesTitle} from '../../mutations/helpers/createMeetingSeriesTitle'
Expand Down Expand Up @@ -156,15 +157,27 @@ const processRecurrence: MutationResolvers['processRecurrence'] = async (_source
return
}

const seriesOrg = await dataLoader.get('organizations').load(seriesTeam.orgId)
const [seriesOrg, lastMeeting] = await Promise.all([
dataLoader.get('organizations').load(seriesTeam.orgId),
dataLoader.get('lastMeetingByMeetingSeriesId').load(meetingSeries.id)
])

// remove this check after 2024-05-05
if (
lastMeeting?.meetingSeriesId !== meetingSeries.id ||
lastMeeting.teamId !== meetingSeries.teamId
) {
const error = new Error(
'lastMeetingByMeetingSeriesId returned a meeting that does not match the series'
)
sendToSentry(error)
throw error
}

if (seriesOrg.lockedAt) {
return
}

const lastMeeting = await dataLoader
.get('lastMeetingByMeetingSeriesId')
.load(meetingSeries.id)

// For meetings that should still be active, start the meeting and set its end time.
// Any subscriptions are handled by the shared meeting start code
const rrule = RRule.fromString(meetingSeries.recurrenceRule)
Expand Down

0 comments on commit eb6e608

Please sign in to comment.