Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8e0e1d5

Browse files
erikjohnstonH-Shay
authored andcommittedMay 31, 2024
Clean out invalid destinations from outbox (element-hq#17242)
We started ensuring we only insert valid destinations: element-hq#17240
1 parent 0c4451a commit 8e0e1d5

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed
 

‎changelog.d/17242.misc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Clean out invalid destinations from `device_federation_outbox` table.

‎synapse/storage/databases/main/deviceinbox.py

+76
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
from synapse.util import json_encoder
5959
from synapse.util.caches.expiringcache import ExpiringCache
6060
from synapse.util.caches.stream_change_cache import StreamChangeCache
61+
from synapse.util.stringutils import parse_and_validate_server_name
6162

6263
if TYPE_CHECKING:
6364
from synapse.server import HomeServer
@@ -964,6 +965,7 @@ def _add_messages_to_local_device_inbox_txn(
964965
class DeviceInboxBackgroundUpdateStore(SQLBaseStore):
965966
DEVICE_INBOX_STREAM_ID = "device_inbox_stream_drop"
966967
REMOVE_DEAD_DEVICES_FROM_INBOX = "remove_dead_devices_from_device_inbox"
968+
CLEANUP_DEVICE_FEDERATION_OUTBOX = "cleanup_device_federation_outbox"
967969

968970
def __init__(
969971
self,
@@ -989,6 +991,11 @@ def __init__(
989991
self._remove_dead_devices_from_device_inbox,
990992
)
991993

994+
self.db_pool.updates.register_background_update_handler(
995+
self.CLEANUP_DEVICE_FEDERATION_OUTBOX,
996+
self._cleanup_device_federation_outbox,
997+
)
998+
992999
async def _background_drop_index_device_inbox(
9931000
self, progress: JsonDict, batch_size: int
9941001
) -> int:
@@ -1080,6 +1087,75 @@ def _remove_dead_devices_from_device_inbox_txn(
10801087

10811088
return batch_size
10821089

1090+
async def _cleanup_device_federation_outbox(
1091+
self,
1092+
progress: JsonDict,
1093+
batch_size: int,
1094+
) -> int:
1095+
def _cleanup_device_federation_outbox_txn(
1096+
txn: LoggingTransaction,
1097+
) -> bool:
1098+
if "max_stream_id" in progress:
1099+
max_stream_id = progress["max_stream_id"]
1100+
else:
1101+
txn.execute("SELECT max(stream_id) FROM device_federation_outbox")
1102+
res = cast(Tuple[Optional[int]], txn.fetchone())
1103+
if res[0] is None:
1104+
# this can only happen if the `device_inbox` table is empty, in which
1105+
# case we have no work to do.
1106+
return True
1107+
else:
1108+
max_stream_id = res[0]
1109+
1110+
start = progress.get("stream_id", 0)
1111+
stop = start + batch_size
1112+
1113+
sql = """
1114+
SELECT destination FROM device_federation_outbox
1115+
WHERE ? < stream_id AND stream_id <= ?
1116+
"""
1117+
1118+
txn.execute(sql, (start, stop))
1119+
1120+
destinations = {d for d, in txn}
1121+
to_remove = set()
1122+
for d in destinations:
1123+
try:
1124+
parse_and_validate_server_name(d)
1125+
except ValueError:
1126+
to_remove.add(d)
1127+
1128+
self.db_pool.simple_delete_many_txn(
1129+
txn,
1130+
table="device_federation_outbox",
1131+
column="destination",
1132+
values=to_remove,
1133+
keyvalues={},
1134+
)
1135+
1136+
self.db_pool.updates._background_update_progress_txn(
1137+
txn,
1138+
self.CLEANUP_DEVICE_FEDERATION_OUTBOX,
1139+
{
1140+
"stream_id": stop,
1141+
"max_stream_id": max_stream_id,
1142+
},
1143+
)
1144+
1145+
return stop >= max_stream_id
1146+
1147+
finished = await self.db_pool.runInteraction(
1148+
"_cleanup_device_federation_outbox",
1149+
_cleanup_device_federation_outbox_txn,
1150+
)
1151+
1152+
if finished:
1153+
await self.db_pool.updates._end_background_update(
1154+
self.CLEANUP_DEVICE_FEDERATION_OUTBOX,
1155+
)
1156+
1157+
return batch_size
1158+
10831159

10841160
class DeviceInboxStore(DeviceInboxWorkerStore, DeviceInboxBackgroundUpdateStore):
10851161
pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--
2+
-- This file is licensed under the Affero General Public License (AGPL) version 3.
3+
--
4+
-- Copyright (C) 2024 New Vector, Ltd
5+
--
6+
-- This program is free software: you can redistribute it and/or modify
7+
-- it under the terms of the GNU Affero General Public License as
8+
-- published by the Free Software Foundation, either version 3 of the
9+
-- License, or (at your option) any later version.
10+
--
11+
-- See the GNU Affero General Public License for more details:
12+
-- <https://www.gnu.org/licenses/agpl-3.0.html>.
13+
14+
INSERT INTO background_updates (ordering, update_name, progress_json) VALUES
15+
(8504, 'cleanup_device_federation_outbox', '{}');

0 commit comments

Comments
 (0)
Please sign in to comment.