Skip to content

Commit

Permalink
Upsert room version when we join over federation (matrix-org#6968)
Browse files Browse the repository at this point in the history
This is intended as a precursor to storing room versions when we receive an
invite over federation, but has the happy side-effect of fixing matrix-org#3374 at last.

In short: change the store_room with try/except to a proper upsert which
updates the right columns.
  • Loading branch information
richvdh authored and phil-flex committed Mar 27, 2020
1 parent c1c4a4d commit 16d09eb
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 10 deletions.
1 change: 1 addition & 0 deletions changelog.d/6968.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix `duplicate key` error which was logged when rejoining a room over federation.
22 changes: 12 additions & 10 deletions synapse/handlers/federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1323,16 +1323,18 @@ async def do_invite_join(

logger.debug("do_invite_join event: %s", event)

try:
await self.store.store_room(
room_id=room_id,
room_creator_user_id="",
is_public=False,
room_version=room_version_obj,
)
except Exception:
# FIXME
pass
# if this is the first time we've joined this room, it's time to add
# a row to `rooms` with the correct room version. If there's already a
# row there, we should override it, since it may have been populated
# based on an invite request which lied about the room version.
#
# federation_client.send_join has already checked that the room
# version in the received create event is the same as room_version_obj,
# so we can rely on it now.
#
await self.store.upsert_room_on_join(
room_id=room_id, room_version=room_version_obj,
)

await self._persist_auth_tree(
origin, auth_chain, state, event, room_version_obj
Expand Down
17 changes: 17 additions & 0 deletions synapse/storage/data_stores/main/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,23 @@ def __init__(self, database: Database, db_conn, hs):

self.config = hs.config

async def upsert_room_on_join(self, room_id: str, room_version: RoomVersion):
"""Ensure that the room is stored in the table
Called when we join a room over federation, and overwrites any room version
currently in the table.
"""
await self.db.simple_upsert(
desc="upsert_room_on_join",
table="rooms",
keyvalues={"room_id": room_id},
values={"room_version": room_version.identifier},
insertion_values={"is_public": False, "creator": ""},
# rooms has a unique constraint on room_id, so no need to lock when doing an
# emulated upsert.
lock=False,
)

@defer.inlineCallbacks
def store_room(
self,
Expand Down

0 comments on commit 16d09eb

Please sign in to comment.