Skip to content

Commit 19c3222

Browse files
Isaac SoloKyle-Shanks
authored andcommitted
Add batching for events by entity ID (#11972)
1 parent a792775 commit 19c3222

File tree

5 files changed

+55
-28
lines changed

5 files changed

+55
-28
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Id, OptionalId } from '@audius/sdk'
2+
import { create, windowScheduler } from '@yornaath/batshit'
3+
import { memoize } from 'lodash'
4+
5+
import { eventMetadataListFromSDK } from '~/adapters/event'
6+
import { ID, Event } from '~/models'
7+
8+
import { contextCacheResolver } from './contextCacheResolver'
9+
import { BatchContext } from './types'
10+
11+
export const getEventsByEntityIdBatcher = memoize(
12+
(context: BatchContext) =>
13+
create({
14+
fetcher: async (entityIds: ID[]): Promise<Event[]> => {
15+
const { sdk, currentUserId } = context
16+
if (!entityIds.length) return []
17+
const { data } = await sdk.events.getEntityEvents({
18+
entityId: entityIds.map((entityId) => Id.parse(entityId)),
19+
userId: OptionalId.parse(currentUserId)
20+
})
21+
22+
return eventMetadataListFromSDK(data)
23+
},
24+
resolver: (events: Event[], entityId: ID) =>
25+
events.filter((event) => event.entityId === entityId), // resolve array of events for entity ID
26+
scheduler: windowScheduler(10)
27+
}),
28+
contextCacheResolver()
29+
)

packages/common/src/api/tan-query/events/useEventsByEntityId.ts

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
import { useMemo } from 'react'
22

3-
import { Id, OptionalId } from '@audius/sdk'
43
import { useQuery, useQueryClient } from '@tanstack/react-query'
4+
import { useDispatch } from 'react-redux'
55

6-
import { eventMetadataFromSDK } from '~/adapters/event'
76
import { useAudiusQueryContext } from '~/audius-query'
87
import { ID } from '~/models'
9-
import { removeNullable } from '~/utils'
108

9+
import { getEventsByEntityIdBatcher } from '../batchers/getEventsByEntityIdBatcher'
1110
import { SelectableQueryOptions } from '../types'
1211
import { useCurrentUserId } from '../useCurrentUserId'
1312

1413
import {
1514
getEventIdsByEntityIdQueryKey,
16-
EventIdsByEntityIdOptions,
17-
getEventQueryKey
15+
EventIdsByEntityIdOptions
1816
} from './utils'
1917

2018
export const useEventIdsByEntityId = (
2119
args: EventIdsByEntityIdOptions,
2220
options?: SelectableQueryOptions<ID[]>
2321
) => {
24-
const { entityId, ...restArgs } = args ?? {}
22+
const { entityId } = args ?? {}
2523
const { audiusSdk } = useAudiusQueryContext()
24+
const dispatch = useDispatch()
2625
const { data: currentUserId } = useCurrentUserId()
2726
const queryClient = useQueryClient()
2827

@@ -33,21 +32,17 @@ export const useEventIdsByEntityId = (
3332
queryKey: getEventIdsByEntityIdQueryKey(args),
3433
queryFn: async () => {
3534
const sdk = await audiusSdk()
36-
const response = await sdk.events.getEntityEvents({
37-
entityId: Id.parse(entityId),
38-
userId: OptionalId.parse(currentUserId),
39-
...restArgs
40-
})
41-
const events = response.data ?? []
42-
const eventsMetadata = events
43-
.map(eventMetadataFromSDK)
44-
.filter(removeNullable)
4535

46-
eventsMetadata.forEach((event) => {
47-
queryClient.setQueryData(getEventQueryKey(event.eventId), event)
36+
const batchGetEvents = getEventsByEntityIdBatcher({
37+
sdk,
38+
currentUserId,
39+
queryClient,
40+
dispatch
4841
})
4942

50-
return eventsMetadata.map((event) => event.eventId)
43+
const events = await batchGetEvents.fetch(entityId!)
44+
45+
return events.map((event) => event.eventId)
5146
},
5247
...options,
5348
enabled: options?.enabled !== false && !!entityId,

packages/discovery-provider/src/api/v1/events.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
abort_not_found,
55
current_user_parser,
66
decode_ids_array,
7-
decode_with_abort,
87
format_limit,
98
format_offset,
109
make_response,
@@ -120,6 +119,7 @@ def get(self):
120119
"entity_id",
121120
required=True,
122121
type=str,
122+
action="append",
123123
description="The ID of the entity to get events for",
124124
)
125125
entity_events_parser.add_argument(
@@ -139,7 +139,7 @@ def get(self):
139139

140140

141141
@ns.route("/entity")
142-
class EntityEvents(Resource):
142+
class BulkEntityEvents(Resource):
143143
@ns.doc(
144144
id="Get Entity Events",
145145
description="Get events for a specific entity",
@@ -151,10 +151,13 @@ class EntityEvents(Resource):
151151
def get(self):
152152
"""Get events for a specific entity"""
153153
args = entity_events_parser.parse_args()
154-
decoded_entity_id = decode_with_abort(args.get("entity_id"), ns)
154+
decoded_entity_ids = decode_ids_array(
155+
args.get("entity_id") if args.get("entity_id") else []
156+
)
157+
155158
events = get_events(
156159
{
157-
"entity_id": decoded_entity_id,
160+
"entity_ids": decoded_entity_ids,
158161
"entity_type": args.get("entity_type"),
159162
"filter_deleted": args.get("filter_deleted", True),
160163
"limit": format_limit(args),

packages/discovery-provider/src/queries/get_events.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ def get_events_by_ids(args) -> List[Event]:
6464
query = query.filter(Event.event_id.in_(ids))
6565
if args.get("event_type") is not None:
6666
query = query.filter(Event.event_type == args.get("event_type"))
67-
events = query.all()
6867

68+
events = helpers.query_result_to_list(query.all())
6969
return format_events(events)
7070

7171

@@ -74,9 +74,9 @@ def _get_events(session, args):
7474
# Create initial query
7575
base_query = session.query(Event)
7676

77-
# Filter by entity_id if provided
78-
if args.get("entity_id") is not None:
79-
base_query = base_query.filter(Event.entity_id == args.get("entity_id"))
77+
# Filter by entity_ids if provided
78+
if args.get("entity_ids") is not None:
79+
base_query = base_query.filter(Event.entity_id.in_(args.get("entity_ids")))
8080

8181
# Filter by entity_type if provided
8282
if args.get("entity_type") is not None:

packages/sdk/src/sdk/api/generated/default/apis/EventsApi.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export interface GetBulkEventsRequest {
4141
}
4242

4343
export interface GetEntityEventsRequest {
44-
entityId: string;
44+
entityId: Array<string>;
4545
offset?: number;
4646
limit?: number;
4747
userId?: string;
@@ -166,7 +166,7 @@ export class EventsApi extends runtime.BaseAPI {
166166
queryParameters['user_id'] = params.userId;
167167
}
168168

169-
if (params.entityId !== undefined) {
169+
if (params.entityId) {
170170
queryParameters['entity_id'] = params.entityId;
171171
}
172172

0 commit comments

Comments
 (0)