Skip to content
This repository was archived by the owner on Mar 26, 2024. It is now read-only.

Commit 7e582a2

Browse files
authored
Improve /sync performance of when passing filters with empty arrays. (matrix-org#14786)
This has two related changes: * It enables fast-path processing for an empty filter (`[]`) which was previously only used for wildcard not-filters (`["*"]`). * It special cases a `/sync` filter with no-rooms to skip all room processing, previously we would partially skip processing, but would generally still calculate intermediate values for each room which were then unused. Future changes might consider further optimizations: * Skip calculating per-room account data when all rooms are filtered (currently this is thrown away). * Make similar improvements to other endpoints which support filters.
1 parent 5e08880 commit 7e582a2

File tree

4 files changed

+21
-9
lines changed

4 files changed

+21
-9
lines changed

changelog.d/14786.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve performance of `/sync` when filtering all rooms, message types, or senders.

synapse/api/filtering.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,9 @@ async def filter_room_account_data(
283283
await self._room_filter.filter(events)
284284
)
285285

286+
def blocks_all_rooms(self) -> bool:
287+
return self._room_filter.filters_all_rooms()
288+
286289
def blocks_all_presence(self) -> bool:
287290
return (
288291
self._presence_filter.filters_all_types()
@@ -351,13 +354,13 @@ def __init__(self, hs: "HomeServer", filter_json: JsonDict):
351354
self.not_rel_types = filter_json.get("org.matrix.msc3874.not_rel_types", [])
352355

353356
def filters_all_types(self) -> bool:
354-
return "*" in self.not_types
357+
return self.types == [] or "*" in self.not_types
355358

356359
def filters_all_senders(self) -> bool:
357-
return "*" in self.not_senders
360+
return self.senders == [] or "*" in self.not_senders
358361

359362
def filters_all_rooms(self) -> bool:
360-
return "*" in self.not_rooms
363+
return self.rooms == [] or "*" in self.not_rooms
361364

362365
def _check(self, event: FilterEvent) -> bool:
363366
"""Checks whether the filter matches the given event.
@@ -450,8 +453,8 @@ def _check_fields(self, field_matchers: Dict[str, Callable[[str], bool]]) -> boo
450453
if any(map(match_func, disallowed_values)):
451454
return False
452455

453-
# Other the event does not match at least one of the allowed values,
454-
# reject it.
456+
# Otherwise if the event does not match at least one of the allowed
457+
# values, reject it.
455458
allowed_values = getattr(self, name)
456459
if allowed_values is not None:
457460
if not any(map(match_func, allowed_values)):

synapse/handlers/search.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ async def _search(
275275
)
276276
room_ids = {r.room_id for r in rooms}
277277

278-
# If doing a subset of all rooms seearch, check if any of the rooms
278+
# If doing a subset of all rooms search, check if any of the rooms
279279
# are from an upgraded room, and search their contents as well
280280
if search_filter.rooms:
281281
historical_room_ids: List[str] = []

synapse/handlers/sync.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,11 +1403,14 @@ async def generate_sync_result(
14031403

14041404
logger.debug("Fetching room data")
14051405

1406-
res = await self._generate_sync_entry_for_rooms(
1406+
(
1407+
newly_joined_rooms,
1408+
newly_joined_or_invited_or_knocked_users,
1409+
newly_left_rooms,
1410+
newly_left_users,
1411+
) = await self._generate_sync_entry_for_rooms(
14071412
sync_result_builder, account_data_by_room
14081413
)
1409-
newly_joined_rooms, newly_joined_or_invited_or_knocked_users, _, _ = res
1410-
_, _, newly_left_rooms, newly_left_users = res
14111414

14121415
block_all_presence_data = (
14131416
since_token is None and sync_config.filter_collection.blocks_all_presence()
@@ -1789,6 +1792,11 @@ async def _generate_sync_entry_for_rooms(
17891792
- newly_left_rooms
17901793
- newly_left_users
17911794
"""
1795+
1796+
# If the request doesn't care about rooms then nothing to do!
1797+
if sync_result_builder.sync_config.filter_collection.blocks_all_rooms():
1798+
return set(), set(), set(), set()
1799+
17921800
since_token = sync_result_builder.since_token
17931801

17941802
# 1. Start by fetching all ephemeral events in rooms we've joined (if required).

0 commit comments

Comments
 (0)