forked from MirrorHub/synapse
Fix infinite loop in partial-state resync (#13353)
Make sure that we only pull out events from the db once they have no prev-events with partial state.
This commit is contained in:
parent
335ebb21cc
commit
ca3db044a3
3 changed files with 27 additions and 8 deletions
1
changelog.d/13353.bugfix
Normal file
1
changelog.d/13353.bugfix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Fix a bug in the experimental faster-room-joins support which could cause it to get stuck in an infinite loop.
|
|
@ -569,15 +569,15 @@ class FederationEventHandler:
|
||||||
|
|
||||||
if context is None or context.partial_state:
|
if context is None or context.partial_state:
|
||||||
# this can happen if some or all of the event's prev_events still have
|
# this can happen if some or all of the event's prev_events still have
|
||||||
# partial state - ie, an event has an earlier stream_ordering than one
|
# partial state. We were careful to only pick events from the db without
|
||||||
# or more of its prev_events, so we de-partial-state it before its
|
# partial-state prev events, so that implies that a prev event has
|
||||||
# prev_events.
|
# been persisted (with partial state) since we did the query.
|
||||||
#
|
#
|
||||||
# TODO(faster_joins): we probably need to be more intelligent, and
|
# So, let's just ignore `event` for now; when we re-run the db query
|
||||||
# exclude partial-state prev_events from consideration
|
# we should instead get its partial-state prev event, which we will
|
||||||
# https://github.com/matrix-org/synapse/issues/13001
|
# de-partial-state, and then come back to event.
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"%s still has partial state: can't de-partial-state it yet",
|
"%s still has prev_events with partial state: can't de-partial-state it yet",
|
||||||
event.event_id,
|
event.event_id,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
|
@ -2110,11 +2110,29 @@ class EventsWorkerStore(SQLBaseStore):
|
||||||
def _get_partial_state_events_batch_txn(
|
def _get_partial_state_events_batch_txn(
|
||||||
txn: LoggingTransaction, room_id: str
|
txn: LoggingTransaction, room_id: str
|
||||||
) -> List[str]:
|
) -> List[str]:
|
||||||
|
# we want to work through the events from oldest to newest, so
|
||||||
|
# we only want events whose prev_events do *not* have partial state - hence
|
||||||
|
# the 'NOT EXISTS' clause in the below.
|
||||||
|
#
|
||||||
|
# This is necessary because ordering by stream ordering isn't quite enough
|
||||||
|
# to ensure that we work from oldest to newest event (in particular,
|
||||||
|
# if an event is initially persisted as an outlier and later de-outliered,
|
||||||
|
# it can end up with a lower stream_ordering than its prev_events).
|
||||||
|
#
|
||||||
|
# Typically this means we'll only return one event per batch, but that's
|
||||||
|
# hard to do much about.
|
||||||
|
#
|
||||||
|
# See also: https://github.com/matrix-org/synapse/issues/13001
|
||||||
txn.execute(
|
txn.execute(
|
||||||
"""
|
"""
|
||||||
SELECT event_id FROM partial_state_events AS pse
|
SELECT event_id FROM partial_state_events AS pse
|
||||||
JOIN events USING (event_id)
|
JOIN events USING (event_id)
|
||||||
WHERE pse.room_id = ?
|
WHERE pse.room_id = ? AND
|
||||||
|
NOT EXISTS(
|
||||||
|
SELECT 1 FROM event_edges AS ee
|
||||||
|
JOIN partial_state_events AS prev_pse ON (prev_pse.event_id=ee.prev_event_id)
|
||||||
|
WHERE ee.event_id=pse.event_id
|
||||||
|
)
|
||||||
ORDER BY events.stream_ordering
|
ORDER BY events.stream_ordering
|
||||||
LIMIT 100
|
LIMIT 100
|
||||||
""",
|
""",
|
||||||
|
|
Loading…
Reference in a new issue