mirror of
https://github.com/element-hq/synapse.git
synced 2024-12-15 17:51:10 +00:00
Speed up room keys query by using read/write lock (#17461)
Linaerizing all access slows things down when devices try and fetch lots of keys on login
This commit is contained in:
parent
73529d3732
commit
ed0face8ad
2 changed files with 10 additions and 9 deletions
1
changelog.d/17461.misc
Normal file
1
changelog.d/17461.misc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Speed up fetching room keys from backup.
|
|
@ -34,7 +34,7 @@ from synapse.api.errors import (
|
||||||
from synapse.logging.opentracing import log_kv, trace
|
from synapse.logging.opentracing import log_kv, trace
|
||||||
from synapse.storage.databases.main.e2e_room_keys import RoomKey
|
from synapse.storage.databases.main.e2e_room_keys import RoomKey
|
||||||
from synapse.types import JsonDict
|
from synapse.types import JsonDict
|
||||||
from synapse.util.async_helpers import Linearizer
|
from synapse.util.async_helpers import ReadWriteLock
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from synapse.server import HomeServer
|
from synapse.server import HomeServer
|
||||||
|
@ -58,7 +58,7 @@ class E2eRoomKeysHandler:
|
||||||
# clients belonging to a user will receive and try to upload a new session at
|
# clients belonging to a user will receive and try to upload a new session at
|
||||||
# roughly the same time. Also used to lock out uploads when the key is being
|
# roughly the same time. Also used to lock out uploads when the key is being
|
||||||
# changed.
|
# changed.
|
||||||
self._upload_linearizer = Linearizer("upload_room_keys_lock")
|
self._upload_lock = ReadWriteLock()
|
||||||
|
|
||||||
@trace
|
@trace
|
||||||
async def get_room_keys(
|
async def get_room_keys(
|
||||||
|
@ -89,7 +89,7 @@ class E2eRoomKeysHandler:
|
||||||
|
|
||||||
# we deliberately take the lock to get keys so that changing the version
|
# we deliberately take the lock to get keys so that changing the version
|
||||||
# works atomically
|
# works atomically
|
||||||
async with self._upload_linearizer.queue(user_id):
|
async with self._upload_lock.read(user_id):
|
||||||
# make sure the backup version exists
|
# make sure the backup version exists
|
||||||
try:
|
try:
|
||||||
await self.store.get_e2e_room_keys_version_info(user_id, version)
|
await self.store.get_e2e_room_keys_version_info(user_id, version)
|
||||||
|
@ -132,7 +132,7 @@ class E2eRoomKeysHandler:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# lock for consistency with uploading
|
# lock for consistency with uploading
|
||||||
async with self._upload_linearizer.queue(user_id):
|
async with self._upload_lock.write(user_id):
|
||||||
# make sure the backup version exists
|
# make sure the backup version exists
|
||||||
try:
|
try:
|
||||||
version_info = await self.store.get_e2e_room_keys_version_info(
|
version_info = await self.store.get_e2e_room_keys_version_info(
|
||||||
|
@ -193,7 +193,7 @@ class E2eRoomKeysHandler:
|
||||||
# TODO: Validate the JSON to make sure it has the right keys.
|
# TODO: Validate the JSON to make sure it has the right keys.
|
||||||
|
|
||||||
# XXX: perhaps we should use a finer grained lock here?
|
# XXX: perhaps we should use a finer grained lock here?
|
||||||
async with self._upload_linearizer.queue(user_id):
|
async with self._upload_lock.write(user_id):
|
||||||
# Check that the version we're trying to upload is the current version
|
# Check that the version we're trying to upload is the current version
|
||||||
try:
|
try:
|
||||||
version_info = await self.store.get_e2e_room_keys_version_info(user_id)
|
version_info = await self.store.get_e2e_room_keys_version_info(user_id)
|
||||||
|
@ -355,7 +355,7 @@ class E2eRoomKeysHandler:
|
||||||
# TODO: Validate the JSON to make sure it has the right keys.
|
# TODO: Validate the JSON to make sure it has the right keys.
|
||||||
|
|
||||||
# lock everyone out until we've switched version
|
# lock everyone out until we've switched version
|
||||||
async with self._upload_linearizer.queue(user_id):
|
async with self._upload_lock.write(user_id):
|
||||||
new_version = await self.store.create_e2e_room_keys_version(
|
new_version = await self.store.create_e2e_room_keys_version(
|
||||||
user_id, version_info
|
user_id, version_info
|
||||||
)
|
)
|
||||||
|
@ -382,7 +382,7 @@ class E2eRoomKeysHandler:
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
async with self._upload_linearizer.queue(user_id):
|
async with self._upload_lock.read(user_id):
|
||||||
try:
|
try:
|
||||||
res = await self.store.get_e2e_room_keys_version_info(user_id, version)
|
res = await self.store.get_e2e_room_keys_version_info(user_id, version)
|
||||||
except StoreError as e:
|
except StoreError as e:
|
||||||
|
@ -407,7 +407,7 @@ class E2eRoomKeysHandler:
|
||||||
NotFoundError: if this backup version doesn't exist
|
NotFoundError: if this backup version doesn't exist
|
||||||
"""
|
"""
|
||||||
|
|
||||||
async with self._upload_linearizer.queue(user_id):
|
async with self._upload_lock.write(user_id):
|
||||||
try:
|
try:
|
||||||
await self.store.delete_e2e_room_keys_version(user_id, version)
|
await self.store.delete_e2e_room_keys_version(user_id, version)
|
||||||
except StoreError as e:
|
except StoreError as e:
|
||||||
|
@ -437,7 +437,7 @@ class E2eRoomKeysHandler:
|
||||||
raise SynapseError(
|
raise SynapseError(
|
||||||
400, "Version in body does not match", Codes.INVALID_PARAM
|
400, "Version in body does not match", Codes.INVALID_PARAM
|
||||||
)
|
)
|
||||||
async with self._upload_linearizer.queue(user_id):
|
async with self._upload_lock.write(user_id):
|
||||||
try:
|
try:
|
||||||
old_info = await self.store.get_e2e_room_keys_version_info(
|
old_info = await self.store.get_e2e_room_keys_version_info(
|
||||||
user_id, version
|
user_id, version
|
||||||
|
|
Loading…
Reference in a new issue