This repository has been archived by the owner on Apr 26, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Claim fallback keys in bulk #16570
Merged
Merged
Claim fallback keys in bulk #16570
Changes from 5 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
0a4276e
Drive-by docstring
861eaf0
Pull out current logic to simple, sqlite-only path
41d325a
Use bulk query on postgres
dc7973b
Changelog
d64b0c4
Remove redundant list() call
f046be9
Drive-by docstring
c79c731
Explicitl test bulk fetching fallback keys
aa15fe4
Fix footgun typo!
4e4a80d
Fix a second test typo
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Improve the performance of claiming encryption keys. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ | |
Mapping, | ||
Optional, | ||
Sequence, | ||
Set, | ||
Tuple, | ||
Union, | ||
cast, | ||
|
@@ -1260,6 +1261,65 @@ async def claim_e2e_fallback_keys( | |
Returns: | ||
A map of user ID -> a map device ID -> a map of key ID -> JSON. | ||
""" | ||
if isinstance(self.database_engine, PostgresEngine): | ||
return await self.db_pool.runInteraction( | ||
"_claim_e2e_fallback_keys_bulk", | ||
self._claim_e2e_fallback_keys_bulk_txn, | ||
query_list, | ||
db_autocommit=True, | ||
) | ||
# Use an UPDATE FROM... RETURNING combined with a VALUES block to do | ||
# everything in one query. Note: this is also supported in SQLite 3.33.0, | ||
# (see https://www.sqlite.org/lang_update.html#update_from), but we do not | ||
# have an equivalent of psycopg2's execute_values to do this in one query. | ||
else: | ||
return await self._claim_e2e_fallback_keys_simple(query_list) | ||
|
||
def _claim_e2e_fallback_keys_bulk_txn( | ||
self, | ||
txn: LoggingTransaction, | ||
query_list: Iterable[Tuple[str, str, str, bool]], | ||
) -> Dict[str, Dict[str, Dict[str, JsonDict]]]: | ||
"""Efficient implementation of claim_e2e_fallback_keys for Postgres. | ||
|
||
Safe to autocommit: this is a single query. | ||
""" | ||
results: Dict[str, Dict[str, Dict[str, JsonDict]]] = {} | ||
|
||
sql = """ | ||
WITH claims(user_id, device_id, algorithm, mark_as_used) AS ( | ||
VALUES ? | ||
) | ||
UPDATE e2e_fallback_keys_json k | ||
SET used = used OR mark_as_used | ||
FROM claims | ||
WHERE (k.user_id, k.device_id, k.algorithm) = (claims.user_id, claims.device_id, claims.algorithm) | ||
RETURNING k.user_id, k.device_id, k.algorithm, k.key_id, k.key_json; | ||
""" | ||
claimed_keys = cast( | ||
List[Tuple[str, str, str, str, str]], | ||
txn.execute_values(sql, query_list), | ||
) | ||
|
||
seen_user_device: Set[Tuple[str, str]] = set() | ||
for user_id, device_id, algorithm, key_id, key_json in claimed_keys: | ||
device_results = results.setdefault(user_id, {}).setdefault(device_id, {}) | ||
device_results[f"{algorithm}:{key_id}"] = json_decoder.decode(key_json) | ||
|
||
if (user_id, device_id) in seen_user_device: | ||
continue | ||
seen_user_device.add((user_id, device_id)) | ||
self._invalidate_cache_and_stream( | ||
txn, self.get_e2e_unused_fallback_key_types, (user_id, device_id) | ||
) | ||
|
||
return results | ||
|
||
async def _claim_e2e_fallback_keys_simple( | ||
self, | ||
query_list: Iterable[Tuple[str, str, str, bool]], | ||
) -> Dict[str, Dict[str, Dict[str, JsonDict]]]: | ||
Comment on lines
+1318
to
+1321
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ouch -- this was doing 2 queries for each item in the input list. |
||
"""Naive, inefficient implementation of claim_e2e_fallback_keys for SQLite.""" | ||
results: Dict[str, Dict[str, Dict[str, JsonDict]]] = {} | ||
for user_id, device_id, algorithm, mark_as_used in query_list: | ||
row = await self.db_pool.simple_select_one( | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The form
WITH ... UPDATE ...
is non-standard, according to https://www.postgresql.org/docs/11/sql-update.html#id-1.9.3.182.10: