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

Commit 19a1cda

Browse files
deepbluev7Mathieu Velten
andauthored
Properly update retry_last_ts when hitting the maximum retry interval (#16156)
* Properly update retry_last_ts when hitting the maximum retry interval This was broken in 1.87 when the maximum retry interval got changed from almost infinite to a week (and made configurable). fixes #16101 Signed-off-by: Nicolas Werner <nicolas.werner@hotmail.de> * Add changelog * Change fix + add test * Add comment --------- Signed-off-by: Nicolas Werner <nicolas.werner@hotmail.de> Co-authored-by: Mathieu Velten <mathieuv@matrix.org>
1 parent dffe095 commit 19a1cda

3 files changed

Lines changed: 55 additions & 1 deletion

File tree

changelog.d/16156.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a bug introduced in 1.87 where synapse would send an excessive amount of federation requests to servers which have been offline for a long time. Contributed by Nico.

synapse/storage/databases/main/transactions.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,8 @@ def _set_destination_retry_timings_txn(
242242
) -> None:
243243
# Upsert retry time interval if retry_interval is zero (i.e. we're
244244
# resetting it) or greater than the existing retry interval.
245+
# We also upsert when the new retry interval is the same as the existing one,
246+
# since it will be the case when `destination_max_retry_interval` is reached.
245247
#
246248
# WARNING: This is executed in autocommit, so we shouldn't add any more
247249
# SQL calls in here (without being very careful).
@@ -257,7 +259,7 @@ def _set_destination_retry_timings_txn(
257259
WHERE
258260
EXCLUDED.retry_interval = 0
259261
OR destinations.retry_interval IS NULL
260-
OR destinations.retry_interval < EXCLUDED.retry_interval
262+
OR destinations.retry_interval <= EXCLUDED.retry_interval
261263
"""
262264

263265
txn.execute(sql, (destination, failure_ts, retry_last_ts, retry_interval))

tests/util/test_retryutils.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,54 @@ def test_limiter(self) -> None:
108108

109109
new_timings = self.get_success(store.get_destination_retry_timings("test_dest"))
110110
self.assertIsNone(new_timings)
111+
112+
def test_max_retry_interval(self) -> None:
113+
"""Test that `destination_max_retry_interval` setting works as expected"""
114+
store = self.hs.get_datastores().main
115+
116+
destination_max_retry_interval_ms = (
117+
self.hs.config.federation.destination_max_retry_interval_ms
118+
)
119+
120+
self.get_success(get_retry_limiter("test_dest", self.clock, store))
121+
self.pump(1)
122+
123+
failure_ts = self.clock.time_msec()
124+
125+
# Simulate reaching destination_max_retry_interval
126+
self.get_success(
127+
store.set_destination_retry_timings(
128+
"test_dest",
129+
failure_ts=failure_ts,
130+
retry_last_ts=failure_ts,
131+
retry_interval=destination_max_retry_interval_ms,
132+
)
133+
)
134+
135+
# Check it fails
136+
self.get_failure(
137+
get_retry_limiter("test_dest", self.clock, store), NotRetryingDestination
138+
)
139+
140+
# Get past retry_interval and we can try again, and still throw an error to continue the backoff
141+
self.reactor.advance(destination_max_retry_interval_ms / 1000 + 1)
142+
limiter = self.get_success(get_retry_limiter("test_dest", self.clock, store))
143+
self.pump(1)
144+
try:
145+
with limiter:
146+
self.pump(1)
147+
raise AssertionError("argh")
148+
except AssertionError:
149+
pass
150+
151+
self.pump()
152+
153+
# retry_interval does not increase and stays at destination_max_retry_interval_ms
154+
new_timings = self.get_success(store.get_destination_retry_timings("test_dest"))
155+
assert new_timings is not None
156+
self.assertEqual(new_timings.retry_interval, destination_max_retry_interval_ms)
157+
158+
# Check it fails
159+
self.get_failure(
160+
get_retry_limiter("test_dest", self.clock, store), NotRetryingDestination
161+
)

0 commit comments

Comments
 (0)