mirror of
https://git.anonymousland.org/anonymousland/synapse-product.git
synced 2024-10-01 08:25:44 -04:00
Limit the length of state chains
This commit is contained in:
parent
9e25443db8
commit
598317927c
@ -497,7 +497,11 @@ class EventsStore(SQLBaseStore):
|
|||||||
|
|
||||||
# insert into the state_group, state_groups_state and
|
# insert into the state_group, state_groups_state and
|
||||||
# event_to_state_groups tables.
|
# event_to_state_groups tables.
|
||||||
|
try:
|
||||||
self._store_mult_state_groups_txn(txn, ((event, context),))
|
self._store_mult_state_groups_txn(txn, ((event, context),))
|
||||||
|
except Exception:
|
||||||
|
logger.exception("")
|
||||||
|
raise
|
||||||
|
|
||||||
metadata_json = encode_json(
|
metadata_json = encode_json(
|
||||||
event.internal_metadata.get_dict()
|
event.internal_metadata.get_dict()
|
||||||
@ -1543,6 +1547,9 @@ class EventsStore(SQLBaseStore):
|
|||||||
)
|
)
|
||||||
event_rows = txn.fetchall()
|
event_rows = txn.fetchall()
|
||||||
|
|
||||||
|
for event_id, state_key in event_rows:
|
||||||
|
txn.call_after(self._get_state_group_for_event.invalidate, (event_id,))
|
||||||
|
|
||||||
# We calculate the new entries for the backward extremeties by finding
|
# We calculate the new entries for the backward extremeties by finding
|
||||||
# all events that point to events that are to be purged
|
# all events that point to events that are to be purged
|
||||||
txn.execute(
|
txn.execute(
|
||||||
@ -1571,26 +1578,26 @@ class EventsStore(SQLBaseStore):
|
|||||||
|
|
||||||
# Get all state groups that are only referenced by events that are
|
# Get all state groups that are only referenced by events that are
|
||||||
# to be deleted.
|
# to be deleted.
|
||||||
txn.execute(
|
# txn.execute(
|
||||||
"SELECT state_group FROM event_to_state_groups"
|
# "SELECT state_group FROM event_to_state_groups"
|
||||||
" INNER JOIN events USING (event_id)"
|
# " INNER JOIN events USING (event_id)"
|
||||||
" WHERE state_group IN ("
|
# " WHERE state_group IN ("
|
||||||
" SELECT DISTINCT state_group FROM events"
|
# " SELECT DISTINCT state_group FROM events"
|
||||||
" INNER JOIN event_to_state_groups USING (event_id)"
|
# " INNER JOIN event_to_state_groups USING (event_id)"
|
||||||
" WHERE room_id = ? AND topological_ordering < ?"
|
# " WHERE room_id = ? AND topological_ordering < ?"
|
||||||
" )"
|
# " )"
|
||||||
" GROUP BY state_group HAVING MAX(topological_ordering) < ?",
|
# " GROUP BY state_group HAVING MAX(topological_ordering) < ?",
|
||||||
(room_id, topological_ordering, topological_ordering)
|
# (room_id, topological_ordering, topological_ordering)
|
||||||
)
|
# )
|
||||||
state_rows = txn.fetchall()
|
# state_rows = txn.fetchall()
|
||||||
txn.executemany(
|
# txn.executemany(
|
||||||
"DELETE FROM state_groups_state WHERE state_group = ?",
|
# "DELETE FROM state_groups_state WHERE state_group = ?",
|
||||||
state_rows
|
# state_rows
|
||||||
)
|
# )
|
||||||
txn.executemany(
|
# txn.executemany(
|
||||||
"DELETE FROM state_groups WHERE id = ?",
|
# "DELETE FROM state_groups WHERE id = ?",
|
||||||
state_rows
|
# state_rows
|
||||||
)
|
# )
|
||||||
# Delete all non-state
|
# Delete all non-state
|
||||||
txn.executemany(
|
txn.executemany(
|
||||||
"DELETE FROM event_to_state_groups WHERE event_id = ?",
|
"DELETE FROM event_to_state_groups WHERE event_id = ?",
|
||||||
|
@ -25,6 +25,9 @@ import logging
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
MAX_STATE_DELTA_HOPS = 100
|
||||||
|
|
||||||
|
|
||||||
class StateStore(SQLBaseStore):
|
class StateStore(SQLBaseStore):
|
||||||
""" Keeps track of the state at a given event.
|
""" Keeps track of the state at a given event.
|
||||||
|
|
||||||
@ -104,7 +107,6 @@ class StateStore(SQLBaseStore):
|
|||||||
state_groups[event.event_id] = context.state_group
|
state_groups[event.event_id] = context.state_group
|
||||||
|
|
||||||
if self._have_persisted_state_group_txn(txn, context.state_group):
|
if self._have_persisted_state_group_txn(txn, context.state_group):
|
||||||
logger.info("Already persisted state_group: %r", context.state_group)
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
state_event_ids = dict(context.current_state_ids)
|
state_event_ids = dict(context.current_state_ids)
|
||||||
@ -120,6 +122,10 @@ class StateStore(SQLBaseStore):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if context.prev_group:
|
if context.prev_group:
|
||||||
|
potential_hops = self._count_state_group_hops_txn(
|
||||||
|
txn, context.prev_group
|
||||||
|
)
|
||||||
|
if potential_hops < MAX_STATE_DELTA_HOPS:
|
||||||
self._simple_insert_txn(
|
self._simple_insert_txn(
|
||||||
txn,
|
txn,
|
||||||
table="state_group_edges",
|
table="state_group_edges",
|
||||||
@ -143,6 +149,21 @@ class StateStore(SQLBaseStore):
|
|||||||
for key, state_id in context.delta_ids.items()
|
for key, state_id in context.delta_ids.items()
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
self._simple_insert_many_txn(
|
||||||
|
txn,
|
||||||
|
table="state_groups_state",
|
||||||
|
values=[
|
||||||
|
{
|
||||||
|
"state_group": context.state_group,
|
||||||
|
"room_id": event.room_id,
|
||||||
|
"type": key[0],
|
||||||
|
"state_key": key[1],
|
||||||
|
"event_id": state_id,
|
||||||
|
}
|
||||||
|
for key, state_id in context.current_state_ids.items()
|
||||||
|
],
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self._simple_insert_many_txn(
|
self._simple_insert_many_txn(
|
||||||
txn,
|
txn,
|
||||||
@ -171,6 +192,41 @@ class StateStore(SQLBaseStore):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _count_state_group_hops_txn(self, txn, state_group):
|
||||||
|
if isinstance(self.database_engine, PostgresEngine):
|
||||||
|
sql = ("""
|
||||||
|
WITH RECURSIVE state(state_group) AS (
|
||||||
|
VALUES(?::bigint)
|
||||||
|
UNION ALL
|
||||||
|
SELECT prev_state_group FROM state_group_edges e, state s
|
||||||
|
WHERE s.state_group = e.state_group
|
||||||
|
)
|
||||||
|
SELECT count(*) FROM state;
|
||||||
|
""")
|
||||||
|
|
||||||
|
txn.execute(sql, (state_group,))
|
||||||
|
row = txn.fetchone()
|
||||||
|
if row and row[0]:
|
||||||
|
return row[0]
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
next_group = state_group
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
while next_group:
|
||||||
|
next_group = self._simple_select_one_onecol_txn(
|
||||||
|
txn,
|
||||||
|
table="state_group_edges",
|
||||||
|
keyvalues={"state_group": next_group},
|
||||||
|
retcol="prev_state_group",
|
||||||
|
allow_none=True,
|
||||||
|
)
|
||||||
|
if next_group:
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
return count
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_current_state(self, room_id, event_type=None, state_key=""):
|
def get_current_state(self, room_id, event_type=None, state_key=""):
|
||||||
if event_type and state_key is not None:
|
if event_type and state_key is not None:
|
||||||
|
Loading…
Reference in New Issue
Block a user