mirror of
https://github.com/element-hq/synapse.git
synced 2024-12-20 10:55:09 +03:00
Improve perf of sync device lists (#17191)
It's almost always more efficient to query the rooms that have device list changes, rather than looking at the list of all users whose devices have changed and then look for shared rooms.
This commit is contained in:
parent
38f03a09ff
commit
bec0313e1b
3 changed files with 9 additions and 46 deletions
1
changelog.d/17191.misc
Normal file
1
changelog.d/17191.misc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Improve performance of calculating device lists changes in `/sync`.
|
|
@ -1886,38 +1886,13 @@ class SyncHandler:
|
||||||
|
|
||||||
# Step 1a, check for changes in devices of users we share a room
|
# Step 1a, check for changes in devices of users we share a room
|
||||||
# with
|
# with
|
||||||
#
|
users_that_have_changed = (
|
||||||
# We do this in two different ways depending on what we have cached.
|
await self._device_handler.get_device_changes_in_shared_rooms(
|
||||||
# If we already have a list of all the user that have changed since
|
user_id,
|
||||||
# the last sync then it's likely more efficient to compare the rooms
|
sync_result_builder.joined_room_ids,
|
||||||
# they're in with the rooms the syncing user is in.
|
from_token=since_token,
|
||||||
#
|
|
||||||
# If we don't have that info cached then we get all the users that
|
|
||||||
# share a room with our user and check if those users have changed.
|
|
||||||
cache_result = self.store.get_cached_device_list_changes(
|
|
||||||
since_token.device_list_key
|
|
||||||
)
|
|
||||||
if cache_result.hit:
|
|
||||||
changed_users = cache_result.entities
|
|
||||||
|
|
||||||
result = await self.store.get_rooms_for_users(changed_users)
|
|
||||||
|
|
||||||
for changed_user_id, entries in result.items():
|
|
||||||
# Check if the changed user shares any rooms with the user,
|
|
||||||
# or if the changed user is the syncing user (as we always
|
|
||||||
# want to include device list updates of their own devices).
|
|
||||||
if user_id == changed_user_id or any(
|
|
||||||
rid in joined_room_ids for rid in entries
|
|
||||||
):
|
|
||||||
users_that_have_changed.add(changed_user_id)
|
|
||||||
else:
|
|
||||||
users_that_have_changed = (
|
|
||||||
await self._device_handler.get_device_changes_in_shared_rooms(
|
|
||||||
user_id,
|
|
||||||
sync_result_builder.joined_room_ids,
|
|
||||||
from_token=since_token,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Step 1b, check for newly joined rooms
|
# Step 1b, check for newly joined rooms
|
||||||
for room_id in newly_joined_rooms:
|
for room_id in newly_joined_rooms:
|
||||||
|
|
|
@ -70,10 +70,7 @@ from synapse.types import (
|
||||||
from synapse.util import json_decoder, json_encoder
|
from synapse.util import json_decoder, json_encoder
|
||||||
from synapse.util.caches.descriptors import cached, cachedList
|
from synapse.util.caches.descriptors import cached, cachedList
|
||||||
from synapse.util.caches.lrucache import LruCache
|
from synapse.util.caches.lrucache import LruCache
|
||||||
from synapse.util.caches.stream_change_cache import (
|
from synapse.util.caches.stream_change_cache import StreamChangeCache
|
||||||
AllEntitiesChangedResult,
|
|
||||||
StreamChangeCache,
|
|
||||||
)
|
|
||||||
from synapse.util.cancellation import cancellable
|
from synapse.util.cancellation import cancellable
|
||||||
from synapse.util.iterutils import batch_iter
|
from synapse.util.iterutils import batch_iter
|
||||||
from synapse.util.stringutils import shortstr
|
from synapse.util.stringutils import shortstr
|
||||||
|
@ -832,16 +829,6 @@ class DeviceWorkerStore(RoomMemberWorkerStore, EndToEndKeyWorkerStore):
|
||||||
)
|
)
|
||||||
return {device[0]: db_to_json(device[1]) for device in devices}
|
return {device[0]: db_to_json(device[1]) for device in devices}
|
||||||
|
|
||||||
def get_cached_device_list_changes(
|
|
||||||
self,
|
|
||||||
from_key: int,
|
|
||||||
) -> AllEntitiesChangedResult:
|
|
||||||
"""Get set of users whose devices have changed since `from_key`, or None
|
|
||||||
if that information is not in our cache.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return self._device_list_stream_cache.get_all_entities_changed(from_key)
|
|
||||||
|
|
||||||
@cancellable
|
@cancellable
|
||||||
async def get_all_devices_changed(
|
async def get_all_devices_changed(
|
||||||
self,
|
self,
|
||||||
|
@ -1475,7 +1462,7 @@ class DeviceWorkerStore(RoomMemberWorkerStore, EndToEndKeyWorkerStore):
|
||||||
|
|
||||||
sql = """
|
sql = """
|
||||||
SELECT DISTINCT user_id FROM device_lists_changes_in_room
|
SELECT DISTINCT user_id FROM device_lists_changes_in_room
|
||||||
WHERE {clause} AND stream_id >= ?
|
WHERE {clause} AND stream_id > ?
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _get_device_list_changes_in_rooms_txn(
|
def _get_device_list_changes_in_rooms_txn(
|
||||||
|
|
Loading…
Reference in a new issue