Sync hot-path optimisation for `filter_events_for_client`

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
pull/13871/head
Michael Telatynski 2022-09-22 11:46:57 +01:00
parent 1a1abdda42
commit 99926affef
No known key found for this signature in database
GPG Key ID: 98BC6A2B829297FE
2 changed files with 12 additions and 5 deletions

View File

@ -539,6 +539,7 @@ class SyncHandler:
sync_config.user.to_string(), sync_config.user.to_string(),
recents, recents,
always_include_ids=current_state_ids, always_include_ids=current_state_ids,
limit=timeline_limit + 1,
) )
log_kv({"recents_after_visibility_filtering": len(recents)}) log_kv({"recents_after_visibility_filtering": len(recents)})
else: else:
@ -616,6 +617,7 @@ class SyncHandler:
sync_config.user.to_string(), sync_config.user.to_string(),
loaded_recents, loaded_recents,
always_include_ids=current_state_ids, always_include_ids=current_state_ids,
limit=timeline_limit + 1 - len(recents),
) )
log_kv({"loaded_recents_after_client_filtering": len(loaded_recents)}) log_kv({"loaded_recents_after_client_filtering": len(loaded_recents)})

View File

@ -60,6 +60,7 @@ async def filter_events_for_client(
is_peeking: bool = False, is_peeking: bool = False,
always_include_ids: FrozenSet[str] = frozenset(), always_include_ids: FrozenSet[str] = frozenset(),
filter_send_to_client: bool = True, filter_send_to_client: bool = True,
limit: int = -1,
) -> List[EventBase]: ) -> List[EventBase]:
""" """
Check which events a user is allowed to see. If the user can see the event but its Check which events a user is allowed to see. If the user can see the event but its
@ -78,6 +79,7 @@ async def filter_events_for_client(
filter_send_to_client: Whether we're checking an event that's going to be filter_send_to_client: Whether we're checking an event that's going to be
sent to a client. This might not always be the case since this function can sent to a client. This might not always be the case since this function can
also be called to check whether a user can see the state at a given point. also be called to check whether a user can see the state at a given point.
limit: The number of events to bail at, as a hot path optimisation.
Returns: Returns:
The filtered events. The filtered events.
@ -122,12 +124,15 @@ async def filter_events_for_client(
sender_erased=erased_senders.get(event.sender, False), sender_erased=erased_senders.get(event.sender, False),
) )
# Check each event: gives an iterable of None or (a potentially modified) filtered_events: List[EventBase] = []
# EventBase. for event in events:
filtered_events = map(allowed, events) checked = allowed(event)
if checked is not None:
filtered_events.append(checked)
if len(filtered_events) >= limit >= 0:
break
# Turn it into a list and remove None entries before returning. return filtered_events
return [ev for ev in filtered_events if ev]
async def filter_event_for_clients_with_state( async def filter_event_for_clients_with_state(