Skip to content

Commit 20dea47

Browse files
authored
Revert "Reduce device lists replication traffic. (#17333)"
This reverts commit cf711ac.
1 parent 6e8af83 commit 20dea47

File tree

6 files changed

+48
-89
lines changed

6 files changed

+48
-89
lines changed

changelog.d/17333.misc

Lines changed: 0 additions & 1 deletion
This file was deleted.

synapse/replication/tcp/client.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -114,19 +114,13 @@ async def on_rdata(
114114
"""
115115
all_room_ids: Set[str] = set()
116116
if stream_name == DeviceListsStream.NAME:
117-
if any(not row.is_signature and not row.hosts_calculated for row in rows):
117+
if any(row.entity.startswith("@") and not row.is_signature for row in rows):
118118
prev_token = self.store.get_device_stream_token()
119119
all_room_ids = await self.store.get_all_device_list_changes(
120120
prev_token, token
121121
)
122122
self.store.device_lists_in_rooms_have_changed(all_room_ids, token)
123123

124-
# If we're sending federation we need to update the device lists
125-
# outbound pokes stream change cache with updated hosts.
126-
if self.send_handler and any(row.hosts_calculated for row in rows):
127-
hosts = await self.store.get_destinations_for_device(token)
128-
self.store.device_lists_outbound_pokes_have_changed(hosts, token)
129-
130124
self.store.process_replication_rows(stream_name, instance_name, token, rows)
131125
# NOTE: this must be called after process_replication_rows to ensure any
132126
# cache invalidations are first handled before any stream ID advances.
@@ -439,11 +433,12 @@ async def process_replication_rows(
439433
# The entities are either user IDs (starting with '@') whose devices
440434
# have changed, or remote servers that we need to tell about
441435
# changes.
442-
if any(row.hosts_calculated for row in rows):
443-
hosts = await self.store.get_destinations_for_device(token)
444-
await self.federation_sender.send_device_messages(
445-
hosts, immediate=False
446-
)
436+
hosts = {
437+
row.entity
438+
for row in rows
439+
if not row.entity.startswith("@") and not row.is_signature
440+
}
441+
await self.federation_sender.send_device_messages(hosts, immediate=False)
447442

448443
elif stream_name == ToDeviceStream.NAME:
449444
# The to_device stream includes stuff to be pushed to both local

synapse/replication/tcp/streams/_base.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -549,14 +549,10 @@ class DeviceListsStream(_StreamFromIdGen):
549549

550550
@attr.s(slots=True, frozen=True, auto_attribs=True)
551551
class DeviceListsStreamRow:
552-
user_id: str
552+
entity: str
553553
# Indicates that a user has signed their own device with their user-signing key
554554
is_signature: bool
555555

556-
# Indicates if this is a notification that we've calculated the hosts we
557-
# need to send the update to.
558-
hosts_calculated: bool
559-
560556
NAME = "device_lists"
561557
ROW_TYPE = DeviceListsStreamRow
562558

@@ -598,13 +594,13 @@ async def _update_function(
598594
upper_limit_token = min(upper_limit_token, signatures_to_token)
599595

600596
device_updates = [
601-
(stream_id, (entity, False, hosts))
602-
for stream_id, (entity, hosts) in device_updates
597+
(stream_id, (entity, False))
598+
for stream_id, (entity,) in device_updates
603599
if stream_id <= upper_limit_token
604600
]
605601

606602
signatures_updates = [
607-
(stream_id, (entity, True, False))
603+
(stream_id, (entity, True))
608604
for stream_id, (entity,) in signatures_updates
609605
if stream_id <= upper_limit_token
610606
]

synapse/storage/databases/main/devices.py

Lines changed: 35 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -164,24 +164,22 @@ def __init__(
164164
prefilled_cache=user_signature_stream_prefill,
165165
)
166166

167-
self._device_list_federation_stream_cache = None
168-
if hs.should_send_federation():
169-
(
170-
device_list_federation_prefill,
171-
device_list_federation_list_id,
172-
) = self.db_pool.get_cache_dict(
173-
db_conn,
174-
"device_lists_outbound_pokes",
175-
entity_column="destination",
176-
stream_column="stream_id",
177-
max_value=device_list_max,
178-
limit=10000,
179-
)
180-
self._device_list_federation_stream_cache = StreamChangeCache(
181-
"DeviceListFederationStreamChangeCache",
182-
device_list_federation_list_id,
183-
prefilled_cache=device_list_federation_prefill,
184-
)
167+
(
168+
device_list_federation_prefill,
169+
device_list_federation_list_id,
170+
) = self.db_pool.get_cache_dict(
171+
db_conn,
172+
"device_lists_outbound_pokes",
173+
entity_column="destination",
174+
stream_column="stream_id",
175+
max_value=device_list_max,
176+
limit=10000,
177+
)
178+
self._device_list_federation_stream_cache = StreamChangeCache(
179+
"DeviceListFederationStreamChangeCache",
180+
device_list_federation_list_id,
181+
prefilled_cache=device_list_federation_prefill,
182+
)
185183

186184
if hs.config.worker.run_background_tasks:
187185
self._clock.looping_call(
@@ -209,29 +207,22 @@ def _invalidate_caches_for_devices(
209207
) -> None:
210208
for row in rows:
211209
if row.is_signature:
212-
self._user_signature_stream_cache.entity_has_changed(row.user_id, token)
210+
self._user_signature_stream_cache.entity_has_changed(row.entity, token)
213211
continue
214212

215213
# The entities are either user IDs (starting with '@') whose devices
216214
# have changed, or remote servers that we need to tell about
217215
# changes.
218-
if not row.hosts_calculated:
219-
self._device_list_stream_cache.entity_has_changed(row.user_id, token)
220-
self.get_cached_devices_for_user.invalidate((row.user_id,))
221-
self._get_cached_user_device.invalidate((row.user_id,))
222-
self.get_device_list_last_stream_id_for_remote.invalidate(
223-
(row.user_id,)
224-
)
216+
if row.entity.startswith("@"):
217+
self._device_list_stream_cache.entity_has_changed(row.entity, token)
218+
self.get_cached_devices_for_user.invalidate((row.entity,))
219+
self._get_cached_user_device.invalidate((row.entity,))
220+
self.get_device_list_last_stream_id_for_remote.invalidate((row.entity,))
225221

226-
def device_lists_outbound_pokes_have_changed(
227-
self, destinations: StrCollection, token: int
228-
) -> None:
229-
assert self._device_list_federation_stream_cache is not None
230-
231-
for destination in destinations:
232-
self._device_list_federation_stream_cache.entity_has_changed(
233-
destination, token
234-
)
222+
else:
223+
self._device_list_federation_stream_cache.entity_has_changed(
224+
row.entity, token
225+
)
235226

236227
def device_lists_in_rooms_have_changed(
237228
self, room_ids: StrCollection, token: int
@@ -372,11 +363,6 @@ async def get_device_updates_by_remote(
372363
EDU contents.
373364
"""
374365
now_stream_id = self.get_device_stream_token()
375-
if from_stream_id == now_stream_id:
376-
return now_stream_id, []
377-
378-
if self._device_list_federation_stream_cache is None:
379-
raise Exception("Func can only be used on federation senders")
380366

381367
has_changed = self._device_list_federation_stream_cache.has_entity_changed(
382368
destination, int(from_stream_id)
@@ -1032,10 +1018,10 @@ def _get_all_device_list_changes_for_remotes(
10321018
# This query Does The Right Thing where it'll correctly apply the
10331019
# bounds to the inner queries.
10341020
sql = """
1035-
SELECT stream_id, user_id, hosts FROM (
1036-
SELECT stream_id, user_id, false AS hosts FROM device_lists_stream
1021+
SELECT stream_id, entity FROM (
1022+
SELECT stream_id, user_id AS entity FROM device_lists_stream
10371023
UNION ALL
1038-
SELECT DISTINCT stream_id, user_id, true AS hosts FROM device_lists_outbound_pokes
1024+
SELECT stream_id, destination AS entity FROM device_lists_outbound_pokes
10391025
) AS e
10401026
WHERE ? < stream_id AND stream_id <= ?
10411027
ORDER BY stream_id ASC
@@ -1591,14 +1577,6 @@ def get_device_list_changes_in_room_txn(
15911577
get_device_list_changes_in_room_txn,
15921578
)
15931579

1594-
async def get_destinations_for_device(self, stream_id: int) -> StrCollection:
1595-
return await self.db_pool.simple_select_onecol(
1596-
table="device_lists_outbound_pokes",
1597-
keyvalues={"stream_id": stream_id},
1598-
retcol="destination",
1599-
desc="get_destinations_for_device",
1600-
)
1601-
16021580

16031581
class DeviceBackgroundUpdateStore(SQLBaseStore):
16041582
def __init__(
@@ -2134,13 +2112,12 @@ def _add_device_outbound_poke_to_stream_txn(
21342112
stream_ids: List[int],
21352113
context: Optional[Dict[str, str]],
21362114
) -> None:
2137-
if self._device_list_federation_stream_cache:
2138-
for host in hosts:
2139-
txn.call_after(
2140-
self._device_list_federation_stream_cache.entity_has_changed,
2141-
host,
2142-
stream_ids[-1],
2143-
)
2115+
for host in hosts:
2116+
txn.call_after(
2117+
self._device_list_federation_stream_cache.entity_has_changed,
2118+
host,
2119+
stream_ids[-1],
2120+
)
21442121

21452122
now = self._clock.time_msec()
21462123
stream_id_iterator = iter(stream_ids)

synapse/storage/databases/main/end_to_end_keys.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@ def process_replication_rows(
123123
if stream_name == DeviceListsStream.NAME:
124124
for row in rows:
125125
assert isinstance(row, DeviceListsStream.DeviceListsStreamRow)
126-
if not row.hosts_calculated:
126+
if row.entity.startswith("@"):
127127
self._get_e2e_device_keys_for_federation_query_inner.invalidate(
128-
(row.user_id,)
128+
(row.entity,)
129129
)
130130

131131
super().process_replication_rows(stream_name, instance_name, token, rows)

tests/storage/test_devices.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,6 @@ class DeviceStoreTestCase(HomeserverTestCase):
3636
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
3737
self.store = hs.get_datastores().main
3838

39-
def default_config(self) -> JsonDict:
40-
config = super().default_config()
41-
42-
# We 'enable' federation otherwise `get_device_updates_by_remote` will
43-
# throw an exception.
44-
config["federation_sender_instances"] = ["master"]
45-
return config
46-
4739
def add_device_change(self, user_id: str, device_ids: List[str], host: str) -> None:
4840
"""Add a device list change for the given device to
4941
`device_lists_outbound_pokes` table.

0 commit comments

Comments
 (0)