mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2024-12-26 14:39:21 -05:00
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 <clokep@users.noreply.github.com>
This commit is contained in:
parent
2a3ec6facf
commit
14d593f72d
@ -1 +1 @@
|
|||||||
Add comments to various parts of the `/sync` handler.
|
Refactor various parts of the `/sync` handler.
|
1
changelog.d/11515.misc
Normal file
1
changelog.d/11515.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Refactor various parts of the `/sync` handler.
|
@ -1506,16 +1506,22 @@ class SyncHandler:
|
|||||||
account_data_by_room: Dictionary of per room account data
|
account_data_by_room: Dictionary of per room account data
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Returns a 4-tuple whose entries are:
|
Returns a 4-tuple describing rooms the user has joined or left, and users who've
|
||||||
|
joined or left rooms any rooms the user is in. This gets used later in
|
||||||
|
`_generate_sync_entry_for_device_list`.
|
||||||
|
|
||||||
|
Its entries are:
|
||||||
- newly_joined_rooms
|
- newly_joined_rooms
|
||||||
- newly_joined_or_invited_or_knocked_users
|
- newly_joined_or_invited_or_knocked_users
|
||||||
- newly_left_rooms
|
- newly_left_rooms
|
||||||
- newly_left_users
|
- newly_left_users
|
||||||
"""
|
"""
|
||||||
# Start by fetching all ephemeral events in rooms we've joined (if required).
|
since_token = sync_result_builder.since_token
|
||||||
|
|
||||||
|
# 1. Start by fetching all ephemeral events in rooms we've joined (if required).
|
||||||
user_id = sync_result_builder.sync_config.user.to_string()
|
user_id = sync_result_builder.sync_config.user.to_string()
|
||||||
block_all_room_ephemeral = (
|
block_all_room_ephemeral = (
|
||||||
sync_result_builder.since_token is None
|
since_token is None
|
||||||
and sync_result_builder.sync_config.filter_collection.blocks_all_room_ephemeral()
|
and sync_result_builder.sync_config.filter_collection.blocks_all_room_ephemeral()
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1529,9 +1535,8 @@ class SyncHandler:
|
|||||||
)
|
)
|
||||||
sync_result_builder.now_token = now_token
|
sync_result_builder.now_token = now_token
|
||||||
|
|
||||||
# We check up front if anything has changed, if it hasn't then there is
|
# 2. We check up front if anything has changed, if it hasn't then there is
|
||||||
# no point in going further.
|
# no point in going further.
|
||||||
since_token = sync_result_builder.since_token
|
|
||||||
if not sync_result_builder.full_state:
|
if not sync_result_builder.full_state:
|
||||||
if since_token and not ephemeral_by_room and not account_data_by_room:
|
if since_token and not ephemeral_by_room and not account_data_by_room:
|
||||||
have_changed = await self._have_rooms_changed(sync_result_builder)
|
have_changed = await self._have_rooms_changed(sync_result_builder)
|
||||||
@ -1544,20 +1549,8 @@ class SyncHandler:
|
|||||||
logger.debug("no-oping sync")
|
logger.debug("no-oping sync")
|
||||||
return set(), set(), set(), set()
|
return set(), set(), set(), set()
|
||||||
|
|
||||||
ignored_account_data = (
|
# 3. Work out which rooms need reporting in the sync response.
|
||||||
await self.store.get_global_account_data_by_type_for_user(
|
ignored_users = await self._get_ignored_users(user_id)
|
||||||
AccountDataTypes.IGNORED_USER_LIST, user_id=user_id
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# If there is ignored users account data and it matches the proper type,
|
|
||||||
# then use it.
|
|
||||||
ignored_users: FrozenSet[str] = frozenset()
|
|
||||||
if ignored_account_data:
|
|
||||||
ignored_users_data = ignored_account_data.get("ignored_users", {})
|
|
||||||
if isinstance(ignored_users_data, dict):
|
|
||||||
ignored_users = frozenset(ignored_users_data.keys())
|
|
||||||
|
|
||||||
if since_token:
|
if since_token:
|
||||||
room_changes = await self._get_rooms_changed(
|
room_changes = await self._get_rooms_changed(
|
||||||
sync_result_builder, ignored_users
|
sync_result_builder, ignored_users
|
||||||
@ -1567,7 +1560,6 @@ class SyncHandler:
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
room_changes = await self._get_all_rooms(sync_result_builder, ignored_users)
|
room_changes = await self._get_all_rooms(sync_result_builder, ignored_users)
|
||||||
|
|
||||||
tags_by_room = await self.store.get_tags_for_user(user_id)
|
tags_by_room = await self.store.get_tags_for_user(user_id)
|
||||||
|
|
||||||
log_kv({"rooms_changed": len(room_changes.room_entries)})
|
log_kv({"rooms_changed": len(room_changes.room_entries)})
|
||||||
@ -1578,6 +1570,8 @@ class SyncHandler:
|
|||||||
newly_joined_rooms = room_changes.newly_joined_rooms
|
newly_joined_rooms = room_changes.newly_joined_rooms
|
||||||
newly_left_rooms = room_changes.newly_left_rooms
|
newly_left_rooms = room_changes.newly_left_rooms
|
||||||
|
|
||||||
|
# 4. We need to apply further processing to `room_entries` (rooms considered
|
||||||
|
# joined or archived).
|
||||||
async def handle_room_entries(room_entry: "RoomSyncResultBuilder") -> None:
|
async def handle_room_entries(room_entry: "RoomSyncResultBuilder") -> None:
|
||||||
logger.debug("Generating room entry for %s", room_entry.room_id)
|
logger.debug("Generating room entry for %s", room_entry.room_id)
|
||||||
await self._generate_room_entry(
|
await self._generate_room_entry(
|
||||||
@ -1596,31 +1590,13 @@ class SyncHandler:
|
|||||||
sync_result_builder.invited.extend(invited)
|
sync_result_builder.invited.extend(invited)
|
||||||
sync_result_builder.knocked.extend(knocked)
|
sync_result_builder.knocked.extend(knocked)
|
||||||
|
|
||||||
# Now we want to get any newly joined, invited or knocking users
|
# 5. Work out which users have joined or left rooms we're in. We use this
|
||||||
newly_joined_or_invited_or_knocked_users = set()
|
# to build the device_list part of the sync response in
|
||||||
newly_left_users = set()
|
# `_generate_sync_entry_for_device_list`.
|
||||||
if since_token:
|
(
|
||||||
for joined_sync in sync_result_builder.joined:
|
newly_joined_or_invited_or_knocked_users,
|
||||||
it = itertools.chain(
|
newly_left_users,
|
||||||
joined_sync.timeline.events, joined_sync.state.values()
|
) = sync_result_builder.calculate_user_changes()
|
||||||
)
|
|
||||||
for event in it:
|
|
||||||
if event.type == EventTypes.Member:
|
|
||||||
if (
|
|
||||||
event.membership == Membership.JOIN
|
|
||||||
or event.membership == Membership.INVITE
|
|
||||||
or event.membership == Membership.KNOCK
|
|
||||||
):
|
|
||||||
newly_joined_or_invited_or_knocked_users.add(
|
|
||||||
event.state_key
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
prev_content = event.unsigned.get("prev_content", {})
|
|
||||||
prev_membership = prev_content.get("membership", None)
|
|
||||||
if prev_membership == Membership.JOIN:
|
|
||||||
newly_left_users.add(event.state_key)
|
|
||||||
|
|
||||||
newly_left_users -= newly_joined_or_invited_or_knocked_users
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
set(newly_joined_rooms),
|
set(newly_joined_rooms),
|
||||||
@ -1629,6 +1605,29 @@ class SyncHandler:
|
|||||||
newly_left_users,
|
newly_left_users,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def _get_ignored_users(self, user_id: str) -> FrozenSet[str]:
|
||||||
|
"""Retrieve the users ignored by the given user from their global account_data.
|
||||||
|
|
||||||
|
Returns an empty set if
|
||||||
|
- there is no global account_data entry for ignored_users
|
||||||
|
- there is such an entry, but it's not a JSON object.
|
||||||
|
"""
|
||||||
|
# TODO: Can we `SELECT ignored_user_id FROM ignored_users WHERE ignorer_user_id=?;` instead?
|
||||||
|
ignored_account_data = (
|
||||||
|
await self.store.get_global_account_data_by_type_for_user(
|
||||||
|
AccountDataTypes.IGNORED_USER_LIST, user_id=user_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# If there is ignored users account data and it matches the proper type,
|
||||||
|
# then use it.
|
||||||
|
ignored_users: FrozenSet[str] = frozenset()
|
||||||
|
if ignored_account_data:
|
||||||
|
ignored_users_data = ignored_account_data.get("ignored_users", {})
|
||||||
|
if isinstance(ignored_users_data, dict):
|
||||||
|
ignored_users = frozenset(ignored_users_data.keys())
|
||||||
|
return ignored_users
|
||||||
|
|
||||||
async def _have_rooms_changed(
|
async def _have_rooms_changed(
|
||||||
self, sync_result_builder: "SyncResultBuilder"
|
self, sync_result_builder: "SyncResultBuilder"
|
||||||
) -> bool:
|
) -> bool:
|
||||||
@ -2341,6 +2340,39 @@ class SyncResultBuilder:
|
|||||||
groups: Optional[GroupsSyncResult] = None
|
groups: Optional[GroupsSyncResult] = None
|
||||||
to_device: List[JsonDict] = attr.Factory(list)
|
to_device: List[JsonDict] = attr.Factory(list)
|
||||||
|
|
||||||
|
def calculate_user_changes(self) -> Tuple[Set[str], Set[str]]:
|
||||||
|
"""Work out which other users have joined or left rooms we are joined to.
|
||||||
|
|
||||||
|
This data only is only useful for an incremental sync.
|
||||||
|
|
||||||
|
The SyncResultBuilder is not modified by this function.
|
||||||
|
"""
|
||||||
|
newly_joined_or_invited_or_knocked_users = set()
|
||||||
|
newly_left_users = set()
|
||||||
|
if self.since_token:
|
||||||
|
for joined_sync in self.joined:
|
||||||
|
it = itertools.chain(
|
||||||
|
joined_sync.timeline.events, joined_sync.state.values()
|
||||||
|
)
|
||||||
|
for event in it:
|
||||||
|
if event.type == EventTypes.Member:
|
||||||
|
if (
|
||||||
|
event.membership == Membership.JOIN
|
||||||
|
or event.membership == Membership.INVITE
|
||||||
|
or event.membership == Membership.KNOCK
|
||||||
|
):
|
||||||
|
newly_joined_or_invited_or_knocked_users.add(
|
||||||
|
event.state_key
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
prev_content = event.unsigned.get("prev_content", {})
|
||||||
|
prev_membership = prev_content.get("membership", None)
|
||||||
|
if prev_membership == Membership.JOIN:
|
||||||
|
newly_left_users.add(event.state_key)
|
||||||
|
|
||||||
|
newly_left_users -= newly_joined_or_invited_or_knocked_users
|
||||||
|
return newly_joined_or_invited_or_knocked_users, newly_left_users
|
||||||
|
|
||||||
|
|
||||||
@attr.s(slots=True, auto_attribs=True)
|
@attr.s(slots=True, auto_attribs=True)
|
||||||
class RoomSyncResultBuilder:
|
class RoomSyncResultBuilder:
|
||||||
|
Loading…
Reference in New Issue
Block a user