Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit c69aae9

Browse files
authored
Split up txn for fetching device keys (#15215)
We look up keys in batches, but we should do that outside of the transaction to avoid starving the database pool.
1 parent 41f127e commit c69aae9

File tree

3 files changed

+26
-9
lines changed

3 files changed

+26
-9
lines changed

changelog.d/15215.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Refactor database transaction for query users' devices to reduce database pool contention.

synapse/storage/database.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,15 @@ def new_transaction(
672672
f = cast(types.FunctionType, func) # type: ignore[redundant-cast]
673673
if f.__closure__:
674674
for i, cell in enumerate(f.__closure__):
675-
if inspect.isgenerator(cell.cell_contents):
675+
try:
676+
contents = cell.cell_contents
677+
except ValueError:
678+
# cell.cell_contents can raise if the "cell" is empty,
679+
# which indicates that the variable is currently
680+
# unbound.
681+
continue
682+
683+
if inspect.isgenerator(contents):
676684
logger.error(
677685
"Programming error: function %s references generator %s "
678686
"via its closure",

synapse/storage/databases/main/end_to_end_keys.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,7 @@ async def get_e2e_device_keys_and_signatures(
244244
set_tag("include_all_devices", include_all_devices)
245245
set_tag("include_deleted_devices", include_deleted_devices)
246246

247-
result = await self.db_pool.runInteraction(
248-
"get_e2e_device_keys",
249-
self._get_e2e_device_keys_txn,
247+
result = await self._get_e2e_device_keys(
250248
query_list,
251249
include_all_devices,
252250
include_deleted_devices,
@@ -285,9 +283,8 @@ async def get_e2e_device_keys_and_signatures(
285283
log_kv(result)
286284
return result
287285

288-
def _get_e2e_device_keys_txn(
286+
async def _get_e2e_device_keys(
289287
self,
290-
txn: LoggingTransaction,
291288
query_list: Collection[Tuple[str, Optional[str]]],
292289
include_all_devices: bool = False,
293290
include_deleted_devices: bool = False,
@@ -319,7 +316,7 @@ def _get_e2e_device_keys_txn(
319316

320317
if user_list:
321318
user_id_in_list_clause, user_args = make_in_list_sql_clause(
322-
txn.database_engine, "user_id", user_list
319+
self.database_engine, "user_id", user_list
323320
)
324321
query_clauses.append(user_id_in_list_clause)
325322
query_params_list.append(user_args)
@@ -332,13 +329,16 @@ def _get_e2e_device_keys_txn(
332329
user_device_id_in_list_clause,
333330
user_device_args,
334331
) = make_tuple_in_list_sql_clause(
335-
txn.database_engine, ("user_id", "device_id"), user_device_batch
332+
self.database_engine, ("user_id", "device_id"), user_device_batch
336333
)
337334
query_clauses.append(user_device_id_in_list_clause)
338335
query_params_list.append(user_device_args)
339336

340337
result: Dict[str, Dict[str, Optional[DeviceKeyLookupResult]]] = {}
341-
for query_clause, query_params in zip(query_clauses, query_params_list):
338+
339+
def get_e2e_device_keys_txn(
340+
txn: LoggingTransaction, query_clause: str, query_params: list
341+
) -> None:
342342
sql = (
343343
"SELECT user_id, device_id, "
344344
" d.display_name, "
@@ -361,6 +361,14 @@ def _get_e2e_device_keys_txn(
361361
display_name, db_to_json(key_json) if key_json else None
362362
)
363363

364+
for query_clause, query_params in zip(query_clauses, query_params_list):
365+
await self.db_pool.runInteraction(
366+
"_get_e2e_device_keys",
367+
get_e2e_device_keys_txn,
368+
query_clause,
369+
query_params,
370+
)
371+
364372
if include_deleted_devices:
365373
for user_id, device_id in deleted_devices:
366374
if device_id is None:

0 commit comments

Comments
 (0)