Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Avoid brand new rooms in delete_old_current_state_events #7854

Merged
merged 3 commits into from
Jul 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/7854.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug introduced in Synapse 1.10.0 which could cause a "no create event in auth events" error during room creation.
65 changes: 55 additions & 10 deletions synapse/storage/data_stores/main/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ async def _background_remove_left_rooms(self, progress, batch_size):
last_room_id = progress.get("last_room_id", "")

def _background_remove_left_rooms_txn(txn):
# get a batch of room ids to consider
sql = """
SELECT DISTINCT room_id FROM current_state_events
WHERE room_id > ? ORDER BY room_id LIMIT ?
Expand All @@ -363,24 +364,68 @@ def _background_remove_left_rooms_txn(txn):
if not room_ids:
return True, set()

###########################################################################
#
# exclude rooms where we have active members

sql = """
SELECT room_id
FROM current_state_events
FROM local_current_membership
WHERE
room_id > ? AND room_id <= ?
AND type = 'm.room.member'
AND membership = 'join'
AND state_key LIKE ?
GROUP BY room_id
"""

txn.execute(sql, (last_room_id, room_ids[-1], "%:" + self.server_name))

txn.execute(sql, (last_room_id, room_ids[-1]))
joined_room_ids = {row[0] for row in txn}
to_delete = set(room_ids) - joined_room_ids

###########################################################################
#
# exclude rooms which we are in the process of constructing; these otherwise
# qualify as "rooms with no local users", and would have their
# forward extremities cleaned up.

# the following query will return a list of rooms which have forward
# extremities that are *not* also the create event in the room - ie
# those that are not being created currently.

sql = """
SELECT DISTINCT efe.room_id
FROM event_forward_extremities efe
LEFT JOIN current_state_events cse ON
cse.event_id = efe.event_id
AND cse.type = 'm.room.create'
AND cse.state_key = ''
WHERE
cse.event_id IS NULL
AND efe.room_id > ? AND efe.room_id <= ?
"""

txn.execute(sql, (last_room_id, room_ids[-1]))

# build a set of those rooms within `to_delete` that do not appear in
# the above, leaving us with the rooms in `to_delete` that *are* being
# created.
creating_rooms = to_delete.difference(row[0] for row in txn)
logger.info("skipping rooms which are being created: %s", creating_rooms)

# now remove the rooms being created from the list of those to delete.
#
# (we could have just taken the intersection of `to_delete` with the result
# of the sql query, but it's useful to be able to log `creating_rooms`; and
# having done so, it's quicker to remove the (few) creating rooms from
# `to_delete` than it is to form the intersection with the (larger) list of
# not-creating-rooms)

to_delete -= creating_rooms

left_rooms = set(room_ids) - joined_room_ids
###########################################################################
#
# now clear the state for the rooms

logger.info("Deleting current state left rooms: %r", left_rooms)
logger.info("Deleting current state left rooms: %r", to_delete)

# First we get all users that we still think were joined to the
# room. This is so that we can mark those device lists as
Expand All @@ -391,7 +436,7 @@ def _background_remove_left_rooms_txn(txn):
txn,
table="current_state_events",
column="room_id",
iterable=left_rooms,
iterable=to_delete,
keyvalues={"type": EventTypes.Member, "membership": Membership.JOIN},
retcols=("state_key",),
)
Expand All @@ -403,15 +448,15 @@ def _background_remove_left_rooms_txn(txn):
txn,
table="current_state_events",
column="room_id",
iterable=left_rooms,
iterable=to_delete,
keyvalues={},
)

self.db.simple_delete_many_txn(
txn,
table="event_forward_extremities",
column="room_id",
iterable=left_rooms,
iterable=to_delete,
keyvalues={},
)

Expand Down