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

Commit 14d593f

Browse files
David Robertsonclokep
David Robertson
andauthored
Refactors in _generate_sync_entry_for_rooms (#11515)
* Move sync_token up to the top * Pull out _get_ignored_users * Try to signpost the body of `_generate_sync_entry_for_rooms` * Pull out _calculate_user_changes Co-authored-by: Patrick Cloke <[email protected]>
1 parent 2a3ec6f commit 14d593f

File tree

3 files changed

+79
-46
lines changed

3 files changed

+79
-46
lines changed

changelog.d/11494.misc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Add comments to various parts of the `/sync` handler.
1+
Refactor various parts of the `/sync` handler.

changelog.d/11515.misc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Refactor various parts of the `/sync` handler.

synapse/handlers/sync.py

+77-45
Original file line numberDiff line numberDiff line change
@@ -1506,16 +1506,22 @@ async def _generate_sync_entry_for_rooms(
15061506
account_data_by_room: Dictionary of per room account data
15071507
15081508
Returns:
1509-
Returns a 4-tuple whose entries are:
1509+
Returns a 4-tuple describing rooms the user has joined or left, and users who've
1510+
joined or left rooms any rooms the user is in. This gets used later in
1511+
`_generate_sync_entry_for_device_list`.
1512+
1513+
Its entries are:
15101514
- newly_joined_rooms
15111515
- newly_joined_or_invited_or_knocked_users
15121516
- newly_left_rooms
15131517
- newly_left_users
15141518
"""
1515-
# Start by fetching all ephemeral events in rooms we've joined (if required).
1519+
since_token = sync_result_builder.since_token
1520+
1521+
# 1. Start by fetching all ephemeral events in rooms we've joined (if required).
15161522
user_id = sync_result_builder.sync_config.user.to_string()
15171523
block_all_room_ephemeral = (
1518-
sync_result_builder.since_token is None
1524+
since_token is None
15191525
and sync_result_builder.sync_config.filter_collection.blocks_all_room_ephemeral()
15201526
)
15211527

@@ -1529,9 +1535,8 @@ async def _generate_sync_entry_for_rooms(
15291535
)
15301536
sync_result_builder.now_token = now_token
15311537

1532-
# We check up front if anything has changed, if it hasn't then there is
1538+
# 2. We check up front if anything has changed, if it hasn't then there is
15331539
# no point in going further.
1534-
since_token = sync_result_builder.since_token
15351540
if not sync_result_builder.full_state:
15361541
if since_token and not ephemeral_by_room and not account_data_by_room:
15371542
have_changed = await self._have_rooms_changed(sync_result_builder)
@@ -1544,20 +1549,8 @@ async def _generate_sync_entry_for_rooms(
15441549
logger.debug("no-oping sync")
15451550
return set(), set(), set(), set()
15461551

1547-
ignored_account_data = (
1548-
await self.store.get_global_account_data_by_type_for_user(
1549-
AccountDataTypes.IGNORED_USER_LIST, user_id=user_id
1550-
)
1551-
)
1552-
1553-
# If there is ignored users account data and it matches the proper type,
1554-
# then use it.
1555-
ignored_users: FrozenSet[str] = frozenset()
1556-
if ignored_account_data:
1557-
ignored_users_data = ignored_account_data.get("ignored_users", {})
1558-
if isinstance(ignored_users_data, dict):
1559-
ignored_users = frozenset(ignored_users_data.keys())
1560-
1552+
# 3. Work out which rooms need reporting in the sync response.
1553+
ignored_users = await self._get_ignored_users(user_id)
15611554
if since_token:
15621555
room_changes = await self._get_rooms_changed(
15631556
sync_result_builder, ignored_users
@@ -1567,7 +1560,6 @@ async def _generate_sync_entry_for_rooms(
15671560
)
15681561
else:
15691562
room_changes = await self._get_all_rooms(sync_result_builder, ignored_users)
1570-
15711563
tags_by_room = await self.store.get_tags_for_user(user_id)
15721564

15731565
log_kv({"rooms_changed": len(room_changes.room_entries)})
@@ -1578,6 +1570,8 @@ async def _generate_sync_entry_for_rooms(
15781570
newly_joined_rooms = room_changes.newly_joined_rooms
15791571
newly_left_rooms = room_changes.newly_left_rooms
15801572

1573+
# 4. We need to apply further processing to `room_entries` (rooms considered
1574+
# joined or archived).
15811575
async def handle_room_entries(room_entry: "RoomSyncResultBuilder") -> None:
15821576
logger.debug("Generating room entry for %s", room_entry.room_id)
15831577
await self._generate_room_entry(
@@ -1596,31 +1590,13 @@ async def handle_room_entries(room_entry: "RoomSyncResultBuilder") -> None:
15961590
sync_result_builder.invited.extend(invited)
15971591
sync_result_builder.knocked.extend(knocked)
15981592

1599-
# Now we want to get any newly joined, invited or knocking users
1600-
newly_joined_or_invited_or_knocked_users = set()
1601-
newly_left_users = set()
1602-
if since_token:
1603-
for joined_sync in sync_result_builder.joined:
1604-
it = itertools.chain(
1605-
joined_sync.timeline.events, joined_sync.state.values()
1606-
)
1607-
for event in it:
1608-
if event.type == EventTypes.Member:
1609-
if (
1610-
event.membership == Membership.JOIN
1611-
or event.membership == Membership.INVITE
1612-
or event.membership == Membership.KNOCK
1613-
):
1614-
newly_joined_or_invited_or_knocked_users.add(
1615-
event.state_key
1616-
)
1617-
else:
1618-
prev_content = event.unsigned.get("prev_content", {})
1619-
prev_membership = prev_content.get("membership", None)
1620-
if prev_membership == Membership.JOIN:
1621-
newly_left_users.add(event.state_key)
1622-
1623-
newly_left_users -= newly_joined_or_invited_or_knocked_users
1593+
# 5. Work out which users have joined or left rooms we're in. We use this
1594+
# to build the device_list part of the sync response in
1595+
# `_generate_sync_entry_for_device_list`.
1596+
(
1597+
newly_joined_or_invited_or_knocked_users,
1598+
newly_left_users,
1599+
) = sync_result_builder.calculate_user_changes()
16241600

16251601
return (
16261602
set(newly_joined_rooms),
@@ -1629,6 +1605,29 @@ async def handle_room_entries(room_entry: "RoomSyncResultBuilder") -> None:
16291605
newly_left_users,
16301606
)
16311607

1608+
async def _get_ignored_users(self, user_id: str) -> FrozenSet[str]:
1609+
"""Retrieve the users ignored by the given user from their global account_data.
1610+
1611+
Returns an empty set if
1612+
- there is no global account_data entry for ignored_users
1613+
- there is such an entry, but it's not a JSON object.
1614+
"""
1615+
# TODO: Can we `SELECT ignored_user_id FROM ignored_users WHERE ignorer_user_id=?;` instead?
1616+
ignored_account_data = (
1617+
await self.store.get_global_account_data_by_type_for_user(
1618+
AccountDataTypes.IGNORED_USER_LIST, user_id=user_id
1619+
)
1620+
)
1621+
1622+
# If there is ignored users account data and it matches the proper type,
1623+
# then use it.
1624+
ignored_users: FrozenSet[str] = frozenset()
1625+
if ignored_account_data:
1626+
ignored_users_data = ignored_account_data.get("ignored_users", {})
1627+
if isinstance(ignored_users_data, dict):
1628+
ignored_users = frozenset(ignored_users_data.keys())
1629+
return ignored_users
1630+
16321631
async def _have_rooms_changed(
16331632
self, sync_result_builder: "SyncResultBuilder"
16341633
) -> bool:
@@ -2341,6 +2340,39 @@ class SyncResultBuilder:
23412340
groups: Optional[GroupsSyncResult] = None
23422341
to_device: List[JsonDict] = attr.Factory(list)
23432342

2343+
def calculate_user_changes(self) -> Tuple[Set[str], Set[str]]:
2344+
"""Work out which other users have joined or left rooms we are joined to.
2345+
2346+
This data only is only useful for an incremental sync.
2347+
2348+
The SyncResultBuilder is not modified by this function.
2349+
"""
2350+
newly_joined_or_invited_or_knocked_users = set()
2351+
newly_left_users = set()
2352+
if self.since_token:
2353+
for joined_sync in self.joined:
2354+
it = itertools.chain(
2355+
joined_sync.timeline.events, joined_sync.state.values()
2356+
)
2357+
for event in it:
2358+
if event.type == EventTypes.Member:
2359+
if (
2360+
event.membership == Membership.JOIN
2361+
or event.membership == Membership.INVITE
2362+
or event.membership == Membership.KNOCK
2363+
):
2364+
newly_joined_or_invited_or_knocked_users.add(
2365+
event.state_key
2366+
)
2367+
else:
2368+
prev_content = event.unsigned.get("prev_content", {})
2369+
prev_membership = prev_content.get("membership", None)
2370+
if prev_membership == Membership.JOIN:
2371+
newly_left_users.add(event.state_key)
2372+
2373+
newly_left_users -= newly_joined_or_invited_or_knocked_users
2374+
return newly_joined_or_invited_or_knocked_users, newly_left_users
2375+
23442376

23452377
@attr.s(slots=True, auto_attribs=True)
23462378
class RoomSyncResultBuilder:

0 commit comments

Comments
 (0)