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

Stop getting missing prev_events after we already know their signature is invalid #13816

Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
924ae2b
Track when the pulled event signature fails
MadLittleMods Sep 14, 2022
d240aeb
Add changelog
MadLittleMods Sep 14, 2022
cfb4e88
Fix reference
MadLittleMods Sep 14, 2022
9b390a3
Stop getting missing prev_events after we already know their signatur…
MadLittleMods Sep 15, 2022
3d8507d
Merge branch 'develop' into madlittlemods/13700-track-when-event-sign…
MadLittleMods Sep 23, 2022
88a75cf
Use callback pattern to record signature failures
MadLittleMods Sep 23, 2022
d29ac0b
Add docstring
MadLittleMods Sep 24, 2022
14e39ee
Record failure from get_pdu and add test
MadLittleMods Sep 24, 2022
7898371
Be more selective about which errors to care about
MadLittleMods Sep 30, 2022
43f1d1a
Merge branch 'develop' into madlittlemods/13700-track-when-event-sign…
MadLittleMods Sep 30, 2022
e32b901
Merge branch 'madlittlemods/13700-track-when-event-signature-fails' i…
MadLittleMods Sep 30, 2022
83feb1b
Merge branch 'develop' into madlittlemods/13700-track-when-event-sign…
MadLittleMods Oct 1, 2022
7d102e8
Merge branch 'develop' into madlittlemods/13700-track-when-event-sign…
MadLittleMods Oct 1, 2022
81410b6
Merge branch 'madlittlemods/13700-track-when-event-signature-fails' i…
MadLittleMods Oct 1, 2022
958fd3b
Merge branch 'develop' into madlittlemods/13622-13700-stop-getting-st…
MadLittleMods Oct 3, 2022
e24db41
Weird name and add tests
MadLittleMods Oct 4, 2022
f853e78
Add changelog
MadLittleMods Oct 4, 2022
43fb6b8
Bail early and fix lints
MadLittleMods Oct 4, 2022
03f23b7
Add integration test with backfill
MadLittleMods Oct 4, 2022
99d3e79
Fix lints and better message
MadLittleMods Oct 4, 2022
f11f5b5
Fix test description
MadLittleMods Oct 4, 2022
6878faa
Fix test descriptions
MadLittleMods Oct 4, 2022
f3b443d
Scratch debug changes
MadLittleMods Oct 5, 2022
d135d41
Stop cascading backoff errors
MadLittleMods Oct 5, 2022
4effca9
Remove scratch changes
MadLittleMods Oct 5, 2022
e3cc054
Use custom FederationPullAttemptBackoffError
MadLittleMods Oct 5, 2022
74f9e03
Fix test to reflect no more cascade
MadLittleMods Oct 5, 2022
0b900e1
Better comments from what I've gathered
MadLittleMods Oct 5, 2022
3cb2826
Clarify which error in comments
MadLittleMods Oct 5, 2022
5f313df
Add some clarification to the test comment
MadLittleMods Oct 5, 2022
02e6bdd
Merge branch 'develop' into madlittlemods/13622-13700-stop-getting-st…
MadLittleMods Oct 12, 2022
7f4fdd2
Not a SynapseError
MadLittleMods Oct 12, 2022
89ffbcb
Make sure usages of _compute_event_context_with_maybe_missing_prevs h…
MadLittleMods Oct 12, 2022
354f682
Remove double "recently"
MadLittleMods Oct 12, 2022
e0b0447
Do the calculation in Python because it's more clear when we need res…
MadLittleMods Oct 12, 2022
e72c4e5
Use built-in select many function
MadLittleMods Oct 12, 2022
4e08039
No need for txn
MadLittleMods Oct 12, 2022
b060652
Rename function to reflect functionality
MadLittleMods Oct 12, 2022
b1a0c1b
Fix test description to make it accurate
MadLittleMods Oct 12, 2022
bccd802
Use more standard string interpolation with `logger`
MadLittleMods Oct 15, 2022
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
6 changes: 6 additions & 0 deletions synapse/handlers/federation_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,12 @@ async def _compute_event_context_with_maybe_missing_prevs(
seen = await self._store.have_events_in_timeline(prevs)
missing_prevs = prevs - seen

# Filter out events we've tried to pull recently
prevs_to_ignore = await self.store.filter_events_with_pull_attempt_backoff(
room_id, missing_prevs
)
erikjohnston marked this conversation as resolved.
Show resolved Hide resolved
missing_prevs = missing_prevs - prevs_to_ignore
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved

if not missing_prevs:
return await self._state_handler.compute_event_context(event)

Expand Down
76 changes: 76 additions & 0 deletions synapse/storage/databases/main/event_federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
Iterable,
List,
Optional,
Sequence,
Set,
Tuple,
cast,
Expand Down Expand Up @@ -1530,6 +1531,81 @@ def _record_event_failed_pull_attempt_upsert_txn(

txn.execute(sql, (room_id, event_id, 1, self._clock.time_msec(), cause))

@trace
async def filter_events_with_pull_attempt_backoff(
self,
room_id: str,
event_ids: Sequence[str],
) -> List[str]:
"""
Filter out events that we've failed to pull before
recently. Uses exponential backoff.

Args:
room_id: The room that the events belong to
event_ids: A list of events to filter down

Returns:
List of event_ids that can be attempted to be pulled
"""
return await self.db_pool.runInteraction(
"filter_events_with_pull_attempt_backoff",
self._filter_events_with_pull_attempt_backoff_txn,
room_id,
event_ids,
)

def _filter_events_with_pull_attempt_backoff_txn(
self,
txn: LoggingTransaction,
room_id: str,
event_ids: Sequence[str],
) -> None:
where_event_ids_match_clause, values = make_in_list_sql_clause(
txn.database_engine, "event_id", event_ids
)

sql = """
SELECT event_id FROM event_failed_pull_attempts as failed_backfill_attempt_info
WHERE
failed_backfill_attempt_info.room_id = ?
%s /* where_event_ids_match_clause */
/**
* Exponential back-off (up to the upper bound) so we don't try to
* pull the same event over and over. ex. 2hr, 4hr, 8hr, 16hr, etc.
*
* We use `1 << n` as a power of 2 equivalent for compatibility
* with older SQLites. The left shift equivalent only works with
* powers of 2 because left shift is a binary operation (base-2).
* Otherwise, we would use `power(2, n)` or the power operator, `2^n`.
*/
AND (
failed_backfill_attempt_info.event_id IS NULL
OR ? /* current_time */ >= failed_backfill_attempt_info.last_attempt_ts + (
(1 << {least_function}(failed_backfill_attempt_info.num_attempts, ? /* max doubling steps */))
* ? /* step */
)
)
"""

if isinstance(self.database_engine, PostgresEngine):
least_function = "least"
elif isinstance(self.database_engine, Sqlite3Engine):
least_function = "min"
else:
raise RuntimeError("Unknown database engine")

txn.execute(
sql % (where_event_ids_match_clause, least_function),
(
room_id,
*values,
self._clock.time_msec(),
BACKFILL_EVENT_EXPONENTIAL_BACKOFF_MAXIMUM_DOUBLING_STEPS,
BACKFILL_EVENT_EXPONENTIAL_BACKOFF_STEP_MILLISECONDS,
),
)

async def get_missing_events(
self,
room_id: str,
Expand Down