forked from MirrorHub/synapse
Avoid brand new rooms in delete_old_current_state_events
(#7854)
When considering rooms to clean up in `delete_old_current_state_events`, skip rooms which we are creating, which otherwise look a bit like rooms we have left. Fixes #7834.
This commit is contained in:
parent
97e1159ac1
commit
a57df9b827
2 changed files with 56 additions and 10 deletions
1
changelog.d/7854.bugfix
Normal file
1
changelog.d/7854.bugfix
Normal file
|
@ -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.
|
|
@ -353,6 +353,7 @@ class MainStateBackgroundUpdateStore(RoomMemberWorkerStore):
|
||||||
last_room_id = progress.get("last_room_id", "")
|
last_room_id = progress.get("last_room_id", "")
|
||||||
|
|
||||||
def _background_remove_left_rooms_txn(txn):
|
def _background_remove_left_rooms_txn(txn):
|
||||||
|
# get a batch of room ids to consider
|
||||||
sql = """
|
sql = """
|
||||||
SELECT DISTINCT room_id FROM current_state_events
|
SELECT DISTINCT room_id FROM current_state_events
|
||||||
WHERE room_id > ? ORDER BY room_id LIMIT ?
|
WHERE room_id > ? ORDER BY room_id LIMIT ?
|
||||||
|
@ -363,24 +364,68 @@ class MainStateBackgroundUpdateStore(RoomMemberWorkerStore):
|
||||||
if not room_ids:
|
if not room_ids:
|
||||||
return True, set()
|
return True, set()
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
#
|
||||||
|
# exclude rooms where we have active members
|
||||||
|
|
||||||
sql = """
|
sql = """
|
||||||
SELECT room_id
|
SELECT room_id
|
||||||
FROM current_state_events
|
FROM local_current_membership
|
||||||
WHERE
|
WHERE
|
||||||
room_id > ? AND room_id <= ?
|
room_id > ? AND room_id <= ?
|
||||||
AND type = 'm.room.member'
|
|
||||||
AND membership = 'join'
|
AND membership = 'join'
|
||||||
AND state_key LIKE ?
|
|
||||||
GROUP BY room_id
|
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}
|
joined_room_ids = {row[0] for row in txn}
|
||||||
|
to_delete = set(room_ids) - joined_room_ids
|
||||||
|
|
||||||
left_rooms = 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.
|
||||||
|
|
||||||
logger.info("Deleting current state left rooms: %r", left_rooms)
|
# 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
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
#
|
||||||
|
# now clear the state for the rooms
|
||||||
|
|
||||||
|
logger.info("Deleting current state left rooms: %r", to_delete)
|
||||||
|
|
||||||
# First we get all users that we still think were joined to the
|
# 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
|
# room. This is so that we can mark those device lists as
|
||||||
|
@ -391,7 +436,7 @@ class MainStateBackgroundUpdateStore(RoomMemberWorkerStore):
|
||||||
txn,
|
txn,
|
||||||
table="current_state_events",
|
table="current_state_events",
|
||||||
column="room_id",
|
column="room_id",
|
||||||
iterable=left_rooms,
|
iterable=to_delete,
|
||||||
keyvalues={"type": EventTypes.Member, "membership": Membership.JOIN},
|
keyvalues={"type": EventTypes.Member, "membership": Membership.JOIN},
|
||||||
retcols=("state_key",),
|
retcols=("state_key",),
|
||||||
)
|
)
|
||||||
|
@ -403,7 +448,7 @@ class MainStateBackgroundUpdateStore(RoomMemberWorkerStore):
|
||||||
txn,
|
txn,
|
||||||
table="current_state_events",
|
table="current_state_events",
|
||||||
column="room_id",
|
column="room_id",
|
||||||
iterable=left_rooms,
|
iterable=to_delete,
|
||||||
keyvalues={},
|
keyvalues={},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -411,7 +456,7 @@ class MainStateBackgroundUpdateStore(RoomMemberWorkerStore):
|
||||||
txn,
|
txn,
|
||||||
table="event_forward_extremities",
|
table="event_forward_extremities",
|
||||||
column="room_id",
|
column="room_id",
|
||||||
iterable=left_rooms,
|
iterable=to_delete,
|
||||||
keyvalues={},
|
keyvalues={},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue