@@ -1569,12 +1569,158 @@ async def generate_sync_result(
1569
1569
# See https://github.com/matrix-org/matrix-doc/issues/1144
1570
1570
raise NotImplementedError ()
1571
1571
1572
+ sync_result_builder = await self .get_sync_result_builder (
1573
+ sync_config ,
1574
+ since_token ,
1575
+ full_state ,
1576
+ )
1577
+
1578
+ logger .debug (
1579
+ "Calculating sync response for %r between %s and %s" ,
1580
+ sync_config .user ,
1581
+ sync_result_builder .since_token ,
1582
+ sync_result_builder .now_token ,
1583
+ )
1584
+
1585
+ logger .debug ("Fetching account data" )
1586
+
1587
+ # Global account data is included if it is not filtered out.
1588
+ if not sync_config .filter_collection .blocks_all_global_account_data ():
1589
+ await self ._generate_sync_entry_for_account_data (sync_result_builder )
1590
+
1591
+ # Presence data is included if the server has it enabled and not filtered out.
1592
+ include_presence_data = bool (
1593
+ self .hs_config .server .presence_enabled
1594
+ and not sync_config .filter_collection .blocks_all_presence ()
1595
+ )
1596
+ # Device list updates are sent if a since token is provided.
1597
+ include_device_list_updates = bool (since_token and since_token .device_list_key )
1598
+
1599
+ # If we do not care about the rooms or things which depend on the room
1600
+ # data (namely presence and device list updates), then we can skip
1601
+ # this process completely.
1602
+ device_lists = DeviceListUpdates ()
1603
+ if (
1604
+ not sync_result_builder .sync_config .filter_collection .blocks_all_rooms ()
1605
+ or include_presence_data
1606
+ or include_device_list_updates
1607
+ ):
1608
+ logger .debug ("Fetching room data" )
1609
+
1610
+ # Note that _generate_sync_entry_for_rooms sets sync_result_builder.joined, which
1611
+ # is used in calculate_user_changes below.
1612
+ (
1613
+ newly_joined_rooms ,
1614
+ newly_left_rooms ,
1615
+ ) = await self ._generate_sync_entry_for_rooms (sync_result_builder )
1616
+
1617
+ # Work out which users have joined or left rooms we're in. We use this
1618
+ # to build the presence and device_list parts of the sync response in
1619
+ # `_generate_sync_entry_for_presence` and
1620
+ # `_generate_sync_entry_for_device_list` respectively.
1621
+ if include_presence_data or include_device_list_updates :
1622
+ # This uses the sync_result_builder.joined which is set in
1623
+ # `_generate_sync_entry_for_rooms`, if that didn't find any joined
1624
+ # rooms for some reason it is a no-op.
1625
+ (
1626
+ newly_joined_or_invited_or_knocked_users ,
1627
+ newly_left_users ,
1628
+ ) = sync_result_builder .calculate_user_changes ()
1629
+
1630
+ if include_presence_data :
1631
+ logger .debug ("Fetching presence data" )
1632
+ await self ._generate_sync_entry_for_presence (
1633
+ sync_result_builder ,
1634
+ newly_joined_rooms ,
1635
+ newly_joined_or_invited_or_knocked_users ,
1636
+ )
1637
+
1638
+ if include_device_list_updates :
1639
+ device_lists = await self ._generate_sync_entry_for_device_list (
1640
+ sync_result_builder ,
1641
+ newly_joined_rooms = newly_joined_rooms ,
1642
+ newly_joined_or_invited_or_knocked_users = newly_joined_or_invited_or_knocked_users ,
1643
+ newly_left_rooms = newly_left_rooms ,
1644
+ newly_left_users = newly_left_users ,
1645
+ )
1646
+
1647
+ logger .debug ("Fetching to-device data" )
1648
+ await self ._generate_sync_entry_for_to_device (sync_result_builder )
1649
+
1650
+ logger .debug ("Fetching OTK data" )
1651
+ device_id = sync_config .device_id
1652
+ one_time_keys_count : JsonMapping = {}
1653
+ unused_fallback_key_types : List [str ] = []
1654
+ if device_id :
1655
+ # TODO: We should have a way to let clients differentiate between the states of:
1656
+ # * no change in OTK count since the provided since token
1657
+ # * the server has zero OTKs left for this device
1658
+ # Spec issue: https://github.com/matrix-org/matrix-doc/issues/3298
1659
+ one_time_keys_count = await self .store .count_e2e_one_time_keys (
1660
+ user_id , device_id
1661
+ )
1662
+ unused_fallback_key_types = list (
1663
+ await self .store .get_e2e_unused_fallback_key_types (user_id , device_id )
1664
+ )
1665
+
1666
+ num_events = 0
1667
+
1668
+ # debug for https://github.com/matrix-org/synapse/issues/9424
1669
+ for joined_room in sync_result_builder .joined :
1670
+ num_events += len (joined_room .timeline .events )
1671
+
1672
+ log_kv (
1673
+ {
1674
+ "joined_rooms_in_result" : len (sync_result_builder .joined ),
1675
+ "events_in_result" : num_events ,
1676
+ }
1677
+ )
1678
+
1679
+ logger .debug ("Sync response calculation complete" )
1680
+ return SyncResult (
1681
+ presence = sync_result_builder .presence ,
1682
+ account_data = sync_result_builder .account_data ,
1683
+ joined = sync_result_builder .joined ,
1684
+ invited = sync_result_builder .invited ,
1685
+ knocked = sync_result_builder .knocked ,
1686
+ archived = sync_result_builder .archived ,
1687
+ to_device = sync_result_builder .to_device ,
1688
+ device_lists = device_lists ,
1689
+ device_one_time_keys_count = one_time_keys_count ,
1690
+ device_unused_fallback_key_types = unused_fallback_key_types ,
1691
+ next_batch = sync_result_builder .now_token ,
1692
+ )
1693
+
1694
+ async def get_sync_result_builder (
1695
+ self ,
1696
+ sync_config : SyncConfig ,
1697
+ since_token : Optional [StreamToken ] = None ,
1698
+ full_state : bool = False ,
1699
+ ) -> "SyncResultBuilder" :
1700
+ """
1701
+ Assemble a `SyncResultBuilder` with all of the initial context to
1702
+ start building up the sync response:
1703
+
1704
+ - Membership changes between the last sync and the current sync.
1705
+ - Joined room IDs (minus any rooms to exclude).
1706
+ - Rooms that became fully-stated/un-partial stated since the last sync.
1707
+
1708
+ Args:
1709
+ sync_config: Config/info necessary to process the sync request.
1710
+ since_token: The point in the stream to sync from.
1711
+ full_state: Whether to return the full state for each room.
1712
+
1713
+ Returns:
1714
+ `SyncResultBuilder` ready to start generating parts of the sync response.
1715
+ """
1716
+ user_id = sync_config .user .to_string ()
1717
+
1572
1718
# Note: we get the users room list *before* we get the current token, this
1573
1719
# avoids checking back in history if rooms are joined after the token is fetched.
1574
1720
token_before_rooms = self .event_sources .get_current_token ()
1575
1721
mutable_joined_room_ids = set (await self .store .get_rooms_for_user (user_id ))
1576
1722
1577
- # NB: The now_token gets changed by some of the generate_sync_* methods,
1723
+ # NB: The ` now_token` gets changed by some of the ` generate_sync_*` methods,
1578
1724
# this is due to some of the underlying streams not supporting the ability
1579
1725
# to query up to a given point.
1580
1726
# Always use the `now_token` in `SyncResultBuilder`
@@ -1675,13 +1821,6 @@ async def generate_sync_result(
1675
1821
if room_id not in mutable_rooms_to_exclude
1676
1822
)
1677
1823
1678
- logger .debug (
1679
- "Calculating sync response for %r between %s and %s" ,
1680
- sync_config .user ,
1681
- since_token ,
1682
- now_token ,
1683
- )
1684
-
1685
1824
sync_result_builder = SyncResultBuilder (
1686
1825
sync_config ,
1687
1826
full_state ,
@@ -1693,114 +1832,7 @@ async def generate_sync_result(
1693
1832
membership_change_events = membership_change_events ,
1694
1833
)
1695
1834
1696
- logger .debug ("Fetching account data" )
1697
-
1698
- # Global account data is included if it is not filtered out.
1699
- if not sync_config .filter_collection .blocks_all_global_account_data ():
1700
- await self ._generate_sync_entry_for_account_data (sync_result_builder )
1701
-
1702
- # Presence data is included if the server has it enabled and not filtered out.
1703
- include_presence_data = bool (
1704
- self .hs_config .server .presence_enabled
1705
- and not sync_config .filter_collection .blocks_all_presence ()
1706
- )
1707
- # Device list updates are sent if a since token is provided.
1708
- include_device_list_updates = bool (since_token and since_token .device_list_key )
1709
-
1710
- # If we do not care about the rooms or things which depend on the room
1711
- # data (namely presence and device list updates), then we can skip
1712
- # this process completely.
1713
- device_lists = DeviceListUpdates ()
1714
- if (
1715
- not sync_result_builder .sync_config .filter_collection .blocks_all_rooms ()
1716
- or include_presence_data
1717
- or include_device_list_updates
1718
- ):
1719
- logger .debug ("Fetching room data" )
1720
-
1721
- # Note that _generate_sync_entry_for_rooms sets sync_result_builder.joined, which
1722
- # is used in calculate_user_changes below.
1723
- (
1724
- newly_joined_rooms ,
1725
- newly_left_rooms ,
1726
- ) = await self ._generate_sync_entry_for_rooms (sync_result_builder )
1727
-
1728
- # Work out which users have joined or left rooms we're in. We use this
1729
- # to build the presence and device_list parts of the sync response in
1730
- # `_generate_sync_entry_for_presence` and
1731
- # `_generate_sync_entry_for_device_list` respectively.
1732
- if include_presence_data or include_device_list_updates :
1733
- # This uses the sync_result_builder.joined which is set in
1734
- # `_generate_sync_entry_for_rooms`, if that didn't find any joined
1735
- # rooms for some reason it is a no-op.
1736
- (
1737
- newly_joined_or_invited_or_knocked_users ,
1738
- newly_left_users ,
1739
- ) = sync_result_builder .calculate_user_changes ()
1740
-
1741
- if include_presence_data :
1742
- logger .debug ("Fetching presence data" )
1743
- await self ._generate_sync_entry_for_presence (
1744
- sync_result_builder ,
1745
- newly_joined_rooms ,
1746
- newly_joined_or_invited_or_knocked_users ,
1747
- )
1748
-
1749
- if include_device_list_updates :
1750
- device_lists = await self ._generate_sync_entry_for_device_list (
1751
- sync_result_builder ,
1752
- newly_joined_rooms = newly_joined_rooms ,
1753
- newly_joined_or_invited_or_knocked_users = newly_joined_or_invited_or_knocked_users ,
1754
- newly_left_rooms = newly_left_rooms ,
1755
- newly_left_users = newly_left_users ,
1756
- )
1757
-
1758
- logger .debug ("Fetching to-device data" )
1759
- await self ._generate_sync_entry_for_to_device (sync_result_builder )
1760
-
1761
- logger .debug ("Fetching OTK data" )
1762
- device_id = sync_config .device_id
1763
- one_time_keys_count : JsonMapping = {}
1764
- unused_fallback_key_types : List [str ] = []
1765
- if device_id :
1766
- # TODO: We should have a way to let clients differentiate between the states of:
1767
- # * no change in OTK count since the provided since token
1768
- # * the server has zero OTKs left for this device
1769
- # Spec issue: https://github.com/matrix-org/matrix-doc/issues/3298
1770
- one_time_keys_count = await self .store .count_e2e_one_time_keys (
1771
- user_id , device_id
1772
- )
1773
- unused_fallback_key_types = list (
1774
- await self .store .get_e2e_unused_fallback_key_types (user_id , device_id )
1775
- )
1776
-
1777
- num_events = 0
1778
-
1779
- # debug for https://github.com/matrix-org/synapse/issues/9424
1780
- for joined_room in sync_result_builder .joined :
1781
- num_events += len (joined_room .timeline .events )
1782
-
1783
- log_kv (
1784
- {
1785
- "joined_rooms_in_result" : len (sync_result_builder .joined ),
1786
- "events_in_result" : num_events ,
1787
- }
1788
- )
1789
-
1790
- logger .debug ("Sync response calculation complete" )
1791
- return SyncResult (
1792
- presence = sync_result_builder .presence ,
1793
- account_data = sync_result_builder .account_data ,
1794
- joined = sync_result_builder .joined ,
1795
- invited = sync_result_builder .invited ,
1796
- knocked = sync_result_builder .knocked ,
1797
- archived = sync_result_builder .archived ,
1798
- to_device = sync_result_builder .to_device ,
1799
- device_lists = device_lists ,
1800
- device_one_time_keys_count = one_time_keys_count ,
1801
- device_unused_fallback_key_types = unused_fallback_key_types ,
1802
- next_batch = sync_result_builder .now_token ,
1803
- )
1835
+ return sync_result_builder
1804
1836
1805
1837
@measure_func ("_generate_sync_entry_for_device_list" )
1806
1838
async def _generate_sync_entry_for_device_list (
0 commit comments