Limit the number of devices we delete at once (#14649)

This commit is contained in:
Erik Johnston 2022-12-09 13:31:32 +00:00 committed by GitHub
parent c2de2ca630
commit 94bc21e69f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 4 deletions

View file

@ -1569,11 +1569,15 @@ class DeviceBackgroundUpdateStore(SQLBaseStore):
return rows
async def check_too_many_devices_for_user(self, user_id: str) -> List[str]:
async def check_too_many_devices_for_user(
self, user_id: str, limit: int
) -> List[str]:
"""Check if the user has a lot of devices, and if so return the set of
devices we can prune.
This does *not* return hidden devices or devices with E2E keys.
Returns at most `limit` number of devices, ordered by last seen.
"""
num_devices = await self.db_pool.simple_select_one_onecol(
@ -1614,7 +1618,7 @@ class DeviceBackgroundUpdateStore(SQLBaseStore):
# Now fetch the devices to delete.
sql = """
SELECT DISTINCT device_id FROM devices
SELECT device_id FROM devices
LEFT JOIN e2e_device_keys_json USING (user_id, device_id)
WHERE
user_id = ?
@ -1622,12 +1626,13 @@ class DeviceBackgroundUpdateStore(SQLBaseStore):
AND last_seen < ?
AND key_json IS NULL
ORDER BY last_seen
LIMIT ?
"""
def check_too_many_devices_for_user_txn(
txn: LoggingTransaction,
) -> List[str]:
txn.execute(sql, (user_id, max_last_seen))
txn.execute(sql, (user_id, max_last_seen, limit))
return [device_id for device_id, in txn]
return await self.db_pool.runInteraction(