Skip to content

Commit 0a7b62f

Browse files
erikjohnstonMic92
authored andcommitted
Fix bug where device lists would break sync (element-hq#17292)
If the stream ID in the unconverted table is ahead of the device lists ID gen, then it can break all /sync requests that had an ID from ahead of the table. The fix is to make sure we add the unconverted table to the list of tables we check at start up. Broke in element-hq#17229
1 parent a57b572 commit 0a7b62f

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

changelog.d/17292.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix bug where `/sync` could get stuck due to edge case in device lists handling. Introduced in v1.109.0rc1.

synapse/storage/databases/main/devices.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ def __init__(
108108
("device_lists_outbound_pokes", "instance_name", "stream_id"),
109109
("device_lists_changes_in_room", "instance_name", "stream_id"),
110110
("device_lists_remote_pending", "instance_name", "stream_id"),
111+
(
112+
"device_lists_changes_converted_stream_position",
113+
"instance_name",
114+
"stream_id",
115+
),
111116
],
112117
sequence_name="device_lists_sequence",
113118
writers=["master"],
@@ -2394,15 +2399,16 @@ async def get_device_change_last_converted_pos(self) -> Tuple[int, str]:
23942399
`FALSE` have not been converted.
23952400
"""
23962401

2397-
return cast(
2398-
Tuple[int, str],
2399-
await self.db_pool.simple_select_one(
2400-
table="device_lists_changes_converted_stream_position",
2401-
keyvalues={},
2402-
retcols=["stream_id", "room_id"],
2403-
desc="get_device_change_last_converted_pos",
2404-
),
2402+
# There should be only one row in this table, though we want to
2403+
# future-proof ourselves for when we have multiple rows (one for each
2404+
# instance). So to handle that case we take the minimum of all rows.
2405+
rows = await self.db_pool.simple_select_list(
2406+
table="device_lists_changes_converted_stream_position",
2407+
keyvalues={},
2408+
retcols=["stream_id", "room_id"],
2409+
desc="get_device_change_last_converted_pos",
24052410
)
2411+
return cast(Tuple[int, str], min(rows))
24062412

24072413
async def set_device_change_last_converted_pos(
24082414
self,
@@ -2417,6 +2423,10 @@ async def set_device_change_last_converted_pos(
24172423
await self.db_pool.simple_update_one(
24182424
table="device_lists_changes_converted_stream_position",
24192425
keyvalues={},
2420-
updatevalues={"stream_id": stream_id, "room_id": room_id},
2426+
updatevalues={
2427+
"stream_id": stream_id,
2428+
"instance_name": self._instance_name,
2429+
"room_id": room_id,
2430+
},
24212431
desc="set_device_change_last_converted_pos",
24222432
)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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+
-- Add `instance_name` columns to stream tables to allow them to be used with
15+
-- `MultiWriterIdGenerator`
16+
ALTER TABLE device_lists_changes_converted_stream_position ADD COLUMN instance_name TEXT;

0 commit comments

Comments
 (0)