@@ -1448,41 +1448,67 @@ async def generate_sync_result(
14481448 sync_result_builder
14491449 )
14501450
1451- logger .debug ("Fetching room data" )
1452-
1453- (
1454- newly_joined_rooms ,
1455- newly_joined_or_invited_or_knocked_users ,
1456- newly_left_rooms ,
1457- newly_left_users ,
1458- ) = await self ._generate_sync_entry_for_rooms (
1459- sync_result_builder , account_data_by_room
1460- )
1461-
14621451 # Presence data is included if the server has it enabled and not filtered out.
1463- include_presence_data = (
1452+ include_presence_data = bool (
14641453 self .hs_config .server .use_presence
14651454 and not sync_config .filter_collection .blocks_all_presence ()
14661455 )
1467- if include_presence_data :
1468- logger .debug ("Fetching presence data" )
1469- await self ._generate_sync_entry_for_presence (
1470- sync_result_builder ,
1456+ # Device list updates are sent if a since token is provided.
1457+ include_device_list_updates = bool (since_token and since_token .device_list_key )
1458+
1459+ # If we do not care about the rooms or things which depend on the room
1460+ # data (namely presence and device list updates), then we can skip
1461+ # this process completely.
1462+ device_lists = DeviceListUpdates ()
1463+ if (
1464+ not sync_result_builder .sync_config .filter_collection .blocks_all_rooms ()
1465+ or include_presence_data
1466+ or include_device_list_updates
1467+ ):
1468+ logger .debug ("Fetching room data" )
1469+
1470+ # Note that _generate_sync_entry_for_rooms sets sync_result_builder.joined, which
1471+ # is used in calculate_user_changes below.
1472+ (
14711473 newly_joined_rooms ,
1472- newly_joined_or_invited_or_knocked_users ,
1474+ newly_left_rooms ,
1475+ ) = await self ._generate_sync_entry_for_rooms (
1476+ sync_result_builder , account_data_by_room
14731477 )
14741478
1479+ # Work out which users have joined or left rooms we're in. We use this
1480+ # to build the presence and device_list parts of the sync response in
1481+ # `_generate_sync_entry_for_presence` and
1482+ # `_generate_sync_entry_for_device_list` respectively.
1483+ if include_presence_data or include_device_list_updates :
1484+ # This uses the sync_result_builder.joined which is set in
1485+ # `_generate_sync_entry_for_rooms`, if that didn't find any joined
1486+ # rooms for some reason it is a no-op.
1487+ (
1488+ newly_joined_or_invited_or_knocked_users ,
1489+ newly_left_users ,
1490+ ) = sync_result_builder .calculate_user_changes ()
1491+
1492+ if include_presence_data :
1493+ logger .debug ("Fetching presence data" )
1494+ await self ._generate_sync_entry_for_presence (
1495+ sync_result_builder ,
1496+ newly_joined_rooms ,
1497+ newly_joined_or_invited_or_knocked_users ,
1498+ )
1499+
1500+ if include_device_list_updates :
1501+ device_lists = await self ._generate_sync_entry_for_device_list (
1502+ sync_result_builder ,
1503+ newly_joined_rooms = newly_joined_rooms ,
1504+ newly_joined_or_invited_or_knocked_users = newly_joined_or_invited_or_knocked_users ,
1505+ newly_left_rooms = newly_left_rooms ,
1506+ newly_left_users = newly_left_users ,
1507+ )
1508+
14751509 logger .debug ("Fetching to-device data" )
14761510 await self ._generate_sync_entry_for_to_device (sync_result_builder )
14771511
1478- device_lists = await self ._generate_sync_entry_for_device_list (
1479- sync_result_builder ,
1480- newly_joined_rooms = newly_joined_rooms ,
1481- newly_joined_or_invited_or_knocked_users = newly_joined_or_invited_or_knocked_users ,
1482- newly_left_rooms = newly_left_rooms ,
1483- newly_left_users = newly_left_users ,
1484- )
1485-
14861512 logger .debug ("Fetching OTK data" )
14871513 device_id = sync_config .device_id
14881514 one_time_keys_count : JsonDict = {}
@@ -1551,99 +1577,93 @@ async def _generate_sync_entry_for_device_list(
15511577
15521578 user_id = sync_result_builder .sync_config .user .to_string ()
15531579 since_token = sync_result_builder .since_token
1580+ assert since_token is not None
15541581
15551582 # Take a copy since these fields will be mutated later.
15561583 newly_joined_or_invited_or_knocked_users = set (
15571584 newly_joined_or_invited_or_knocked_users
15581585 )
15591586 newly_left_users = set (newly_left_users )
15601587
1561- if since_token and since_token .device_list_key :
1562- # We want to figure out what user IDs the client should refetch
1563- # device keys for, and which users we aren't going to track changes
1564- # for anymore.
1565- #
1566- # For the first step we check:
1567- # a. if any users we share a room with have updated their devices,
1568- # and
1569- # b. we also check if we've joined any new rooms, or if a user has
1570- # joined a room we're in.
1571- #
1572- # For the second step we just find any users we no longer share a
1573- # room with by looking at all users that have left a room plus users
1574- # that were in a room we've left.
1588+ # We want to figure out what user IDs the client should refetch
1589+ # device keys for, and which users we aren't going to track changes
1590+ # for anymore.
1591+ #
1592+ # For the first step we check:
1593+ # a. if any users we share a room with have updated their devices,
1594+ # and
1595+ # b. we also check if we've joined any new rooms, or if a user has
1596+ # joined a room we're in.
1597+ #
1598+ # For the second step we just find any users we no longer share a
1599+ # room with by looking at all users that have left a room plus users
1600+ # that were in a room we've left.
15751601
1576- users_that_have_changed = set ()
1602+ users_that_have_changed = set ()
15771603
1578- joined_rooms = sync_result_builder .joined_room_ids
1604+ joined_rooms = sync_result_builder .joined_room_ids
15791605
1580- # Step 1a, check for changes in devices of users we share a room
1581- # with
1582- #
1583- # We do this in two different ways depending on what we have cached.
1584- # If we already have a list of all the user that have changed since
1585- # the last sync then it's likely more efficient to compare the rooms
1586- # they're in with the rooms the syncing user is in.
1587- #
1588- # If we don't have that info cached then we get all the users that
1589- # share a room with our user and check if those users have changed.
1590- cache_result = self .store .get_cached_device_list_changes (
1591- since_token .device_list_key
1592- )
1593- if cache_result .hit :
1594- changed_users = cache_result .entities
1595-
1596- result = await self .store .get_rooms_for_users (changed_users )
1597-
1598- for changed_user_id , entries in result .items ():
1599- # Check if the changed user shares any rooms with the user,
1600- # or if the changed user is the syncing user (as we always
1601- # want to include device list updates of their own devices).
1602- if user_id == changed_user_id or any (
1603- rid in joined_rooms for rid in entries
1604- ):
1605- users_that_have_changed .add (changed_user_id )
1606- else :
1607- users_that_have_changed = (
1608- await self ._device_handler .get_device_changes_in_shared_rooms (
1609- user_id ,
1610- sync_result_builder .joined_room_ids ,
1611- from_token = since_token ,
1612- )
1613- )
1614-
1615- # Step 1b, check for newly joined rooms
1616- for room_id in newly_joined_rooms :
1617- joined_users = await self .store .get_users_in_room (room_id )
1618- newly_joined_or_invited_or_knocked_users .update (joined_users )
1606+ # Step 1a, check for changes in devices of users we share a room
1607+ # with
1608+ #
1609+ # We do this in two different ways depending on what we have cached.
1610+ # If we already have a list of all the user that have changed since
1611+ # the last sync then it's likely more efficient to compare the rooms
1612+ # they're in with the rooms the syncing user is in.
1613+ #
1614+ # If we don't have that info cached then we get all the users that
1615+ # share a room with our user and check if those users have changed.
1616+ cache_result = self .store .get_cached_device_list_changes (
1617+ since_token .device_list_key
1618+ )
1619+ if cache_result .hit :
1620+ changed_users = cache_result .entities
16191621
1620- # TODO: Check that these users are actually new, i.e. either they
1621- # weren't in the previous sync *or* they left and rejoined.
1622- users_that_have_changed .update (newly_joined_or_invited_or_knocked_users )
1622+ result = await self .store .get_rooms_for_users (changed_users )
16231623
1624- user_signatures_changed = (
1625- await self .store .get_users_whose_signatures_changed (
1626- user_id , since_token .device_list_key
1624+ for changed_user_id , entries in result .items ():
1625+ # Check if the changed user shares any rooms with the user,
1626+ # or if the changed user is the syncing user (as we always
1627+ # want to include device list updates of their own devices).
1628+ if user_id == changed_user_id or any (
1629+ rid in joined_rooms for rid in entries
1630+ ):
1631+ users_that_have_changed .add (changed_user_id )
1632+ else :
1633+ users_that_have_changed = (
1634+ await self ._device_handler .get_device_changes_in_shared_rooms (
1635+ user_id ,
1636+ sync_result_builder .joined_room_ids ,
1637+ from_token = since_token ,
16271638 )
16281639 )
1629- users_that_have_changed .update (user_signatures_changed )
16301640
1631- # Now find users that we no longer track
1632- for room_id in newly_left_rooms :
1633- left_users = await self .store .get_users_in_room (room_id )
1634- newly_left_users .update (left_users )
1641+ # Step 1b, check for newly joined rooms
1642+ for room_id in newly_joined_rooms :
1643+ joined_users = await self .store .get_users_in_room (room_id )
1644+ newly_joined_or_invited_or_knocked_users .update (joined_users )
16351645
1636- # Remove any users that we still share a room with.
1637- left_users_rooms = await self .store .get_rooms_for_users (newly_left_users )
1638- for user_id , entries in left_users_rooms .items ():
1639- if any (rid in joined_rooms for rid in entries ):
1640- newly_left_users .discard (user_id )
1646+ # TODO: Check that these users are actually new, i.e. either they
1647+ # weren't in the previous sync *or* they left and rejoined.
1648+ users_that_have_changed .update (newly_joined_or_invited_or_knocked_users )
16411649
1642- return DeviceListUpdates (
1643- changed = users_that_have_changed , left = newly_left_users
1644- )
1645- else :
1646- return DeviceListUpdates ()
1650+ user_signatures_changed = await self .store .get_users_whose_signatures_changed (
1651+ user_id , since_token .device_list_key
1652+ )
1653+ users_that_have_changed .update (user_signatures_changed )
1654+
1655+ # Now find users that we no longer track
1656+ for room_id in newly_left_rooms :
1657+ left_users = await self .store .get_users_in_room (room_id )
1658+ newly_left_users .update (left_users )
1659+
1660+ # Remove any users that we still share a room with.
1661+ left_users_rooms = await self .store .get_rooms_for_users (newly_left_users )
1662+ for user_id , entries in left_users_rooms .items ():
1663+ if any (rid in joined_rooms for rid in entries ):
1664+ newly_left_users .discard (user_id )
1665+
1666+ return DeviceListUpdates (changed = users_that_have_changed , left = newly_left_users )
16471667
16481668 @trace
16491669 async def _generate_sync_entry_for_to_device (
@@ -1720,6 +1740,7 @@ async def _generate_sync_entry_for_account_data(
17201740 since_token = sync_result_builder .since_token
17211741
17221742 if since_token and not sync_result_builder .full_state :
1743+ # TODO Do not fetch room account data if it will be unused.
17231744 (
17241745 global_account_data ,
17251746 account_data_by_room ,
@@ -1736,6 +1757,7 @@ async def _generate_sync_entry_for_account_data(
17361757 sync_config .user
17371758 )
17381759 else :
1760+ # TODO Do not fetch room account data if it will be unused.
17391761 (
17401762 global_account_data ,
17411763 account_data_by_room ,
@@ -1818,7 +1840,7 @@ async def _generate_sync_entry_for_rooms(
18181840 self ,
18191841 sync_result_builder : "SyncResultBuilder" ,
18201842 account_data_by_room : Dict [str , Dict [str , JsonDict ]],
1821- ) -> Tuple [AbstractSet [str ], AbstractSet [str ], AbstractSet [ str ], AbstractSet [ str ] ]:
1843+ ) -> Tuple [AbstractSet [str ], AbstractSet [str ]]:
18221844 """Generates the rooms portion of the sync response. Populates the
18231845 `sync_result_builder` with the result.
18241846
@@ -1831,24 +1853,22 @@ async def _generate_sync_entry_for_rooms(
18311853 account_data_by_room: Dictionary of per room account data
18321854
18331855 Returns:
1834- Returns a 4-tuple describing rooms the user has joined or left, and users who've
1835- joined or left rooms any rooms the user is in. This gets used later in
1836- `_generate_sync_entry_for_device_list`.
1856+ Returns a 2-tuple describing rooms the user has joined or left.
18371857
18381858 Its entries are:
18391859 - newly_joined_rooms
1840- - newly_joined_or_invited_or_knocked_users
18411860 - newly_left_rooms
1842- - newly_left_users
18431861 """
18441862
18451863 since_token = sync_result_builder .since_token
18461864 user_id = sync_result_builder .sync_config .user .to_string ()
18471865
18481866 # 1. Start by fetching all ephemeral events in rooms we've joined (if required).
1849- if (
1850- sync_result_builder .sync_config .filter_collection .blocks_all_room_ephemeral ()
1851- ):
1867+ block_all_room_ephemeral = (
1868+ sync_result_builder .sync_config .filter_collection .blocks_all_rooms ()
1869+ or sync_result_builder .sync_config .filter_collection .blocks_all_room_ephemeral ()
1870+ )
1871+ if block_all_room_ephemeral :
18521872 ephemeral_by_room : Dict [str , List [JsonDict ]] = {}
18531873 else :
18541874 now_token , ephemeral_by_room = await self .ephemeral_by_room (
@@ -1870,7 +1890,7 @@ async def _generate_sync_entry_for_rooms(
18701890 )
18711891 if not tags_by_room :
18721892 logger .debug ("no-oping sync" )
1873- return set (), set (), set (), set ()
1893+ return set (), set ()
18741894
18751895 # 3. Work out which rooms need reporting in the sync response.
18761896 ignored_users = await self .store .ignored_users (user_id )
@@ -1899,6 +1919,7 @@ async def _generate_sync_entry_for_rooms(
18991919 # joined or archived).
19001920 async def handle_room_entries (room_entry : "RoomSyncResultBuilder" ) -> None :
19011921 logger .debug ("Generating room entry for %s" , room_entry .room_id )
1922+ # Note that this mutates sync_result_builder.{joined,archived}.
19021923 await self ._generate_room_entry (
19031924 sync_result_builder ,
19041925 room_entry ,
@@ -1915,20 +1936,7 @@ async def handle_room_entries(room_entry: "RoomSyncResultBuilder") -> None:
19151936 sync_result_builder .invited .extend (invited )
19161937 sync_result_builder .knocked .extend (knocked )
19171938
1918- # 5. Work out which users have joined or left rooms we're in. We use this
1919- # to build the device_list part of the sync response in
1920- # `_generate_sync_entry_for_device_list`.
1921- (
1922- newly_joined_or_invited_or_knocked_users ,
1923- newly_left_users ,
1924- ) = sync_result_builder .calculate_user_changes ()
1925-
1926- return (
1927- set (newly_joined_rooms ),
1928- newly_joined_or_invited_or_knocked_users ,
1929- set (newly_left_rooms ),
1930- newly_left_users ,
1931- )
1939+ return set (newly_joined_rooms ), set (newly_left_rooms )
19321940
19331941 async def _have_rooms_changed (
19341942 self , sync_result_builder : "SyncResultBuilder"
0 commit comments