@@ -1448,41 +1448,67 @@ async def generate_sync_result(
1448
1448
sync_result_builder
1449
1449
)
1450
1450
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
-
1462
1451
# Presence data is included if the server has it enabled and not filtered out.
1463
- include_presence_data = (
1452
+ include_presence_data = bool (
1464
1453
self .hs_config .server .use_presence
1465
1454
and not sync_config .filter_collection .blocks_all_presence ()
1466
1455
)
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
+ (
1471
1473
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
1473
1477
)
1474
1478
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
+
1475
1509
logger .debug ("Fetching to-device data" )
1476
1510
await self ._generate_sync_entry_for_to_device (sync_result_builder )
1477
1511
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
-
1486
1512
logger .debug ("Fetching OTK data" )
1487
1513
device_id = sync_config .device_id
1488
1514
one_time_keys_count : JsonDict = {}
@@ -1551,99 +1577,93 @@ async def _generate_sync_entry_for_device_list(
1551
1577
1552
1578
user_id = sync_result_builder .sync_config .user .to_string ()
1553
1579
since_token = sync_result_builder .since_token
1580
+ assert since_token is not None
1554
1581
1555
1582
# Take a copy since these fields will be mutated later.
1556
1583
newly_joined_or_invited_or_knocked_users = set (
1557
1584
newly_joined_or_invited_or_knocked_users
1558
1585
)
1559
1586
newly_left_users = set (newly_left_users )
1560
1587
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.
1575
1601
1576
- users_that_have_changed = set ()
1602
+ users_that_have_changed = set ()
1577
1603
1578
- joined_rooms = sync_result_builder .joined_room_ids
1604
+ joined_rooms = sync_result_builder .joined_room_ids
1579
1605
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
1619
1621
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 )
1623
1623
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 ,
1627
1638
)
1628
1639
)
1629
- users_that_have_changed .update (user_signatures_changed )
1630
1640
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 )
1635
1645
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 )
1641
1649
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 )
1647
1667
1648
1668
@trace
1649
1669
async def _generate_sync_entry_for_to_device (
@@ -1720,6 +1740,7 @@ async def _generate_sync_entry_for_account_data(
1720
1740
since_token = sync_result_builder .since_token
1721
1741
1722
1742
if since_token and not sync_result_builder .full_state :
1743
+ # TODO Do not fetch room account data if it will be unused.
1723
1744
(
1724
1745
global_account_data ,
1725
1746
account_data_by_room ,
@@ -1736,6 +1757,7 @@ async def _generate_sync_entry_for_account_data(
1736
1757
sync_config .user
1737
1758
)
1738
1759
else :
1760
+ # TODO Do not fetch room account data if it will be unused.
1739
1761
(
1740
1762
global_account_data ,
1741
1763
account_data_by_room ,
@@ -1818,7 +1840,7 @@ async def _generate_sync_entry_for_rooms(
1818
1840
self ,
1819
1841
sync_result_builder : "SyncResultBuilder" ,
1820
1842
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 ]]:
1822
1844
"""Generates the rooms portion of the sync response. Populates the
1823
1845
`sync_result_builder` with the result.
1824
1846
@@ -1831,24 +1853,22 @@ async def _generate_sync_entry_for_rooms(
1831
1853
account_data_by_room: Dictionary of per room account data
1832
1854
1833
1855
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.
1837
1857
1838
1858
Its entries are:
1839
1859
- newly_joined_rooms
1840
- - newly_joined_or_invited_or_knocked_users
1841
1860
- newly_left_rooms
1842
- - newly_left_users
1843
1861
"""
1844
1862
1845
1863
since_token = sync_result_builder .since_token
1846
1864
user_id = sync_result_builder .sync_config .user .to_string ()
1847
1865
1848
1866
# 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 :
1852
1872
ephemeral_by_room : Dict [str , List [JsonDict ]] = {}
1853
1873
else :
1854
1874
now_token , ephemeral_by_room = await self .ephemeral_by_room (
@@ -1870,7 +1890,7 @@ async def _generate_sync_entry_for_rooms(
1870
1890
)
1871
1891
if not tags_by_room :
1872
1892
logger .debug ("no-oping sync" )
1873
- return set (), set (), set (), set ()
1893
+ return set (), set ()
1874
1894
1875
1895
# 3. Work out which rooms need reporting in the sync response.
1876
1896
ignored_users = await self .store .ignored_users (user_id )
@@ -1899,6 +1919,7 @@ async def _generate_sync_entry_for_rooms(
1899
1919
# joined or archived).
1900
1920
async def handle_room_entries (room_entry : "RoomSyncResultBuilder" ) -> None :
1901
1921
logger .debug ("Generating room entry for %s" , room_entry .room_id )
1922
+ # Note that this mutates sync_result_builder.{joined,archived}.
1902
1923
await self ._generate_room_entry (
1903
1924
sync_result_builder ,
1904
1925
room_entry ,
@@ -1915,20 +1936,7 @@ async def handle_room_entries(room_entry: "RoomSyncResultBuilder") -> None:
1915
1936
sync_result_builder .invited .extend (invited )
1916
1937
sync_result_builder .knocked .extend (knocked )
1917
1938
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 )
1932
1940
1933
1941
async def _have_rooms_changed (
1934
1942
self , sync_result_builder : "SyncResultBuilder"
0 commit comments