mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-05-02 08:16:02 -04:00
Merge pull request #2050 from matrix-org/rav/federation_backoff
push federation retry limiter down to matrixfederationclient
This commit is contained in:
commit
9397edb28b
12 changed files with 359 additions and 319 deletions
|
@ -35,7 +35,8 @@ class NotRetryingDestination(Exception):
|
|||
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def get_retry_limiter(destination, clock, store, **kwargs):
|
||||
def get_retry_limiter(destination, clock, store, ignore_backoff=False,
|
||||
**kwargs):
|
||||
"""For a given destination check if we have previously failed to
|
||||
send a request there and are waiting before retrying the destination.
|
||||
If we are not ready to retry the destination, this will raise a
|
||||
|
@ -43,6 +44,14 @@ def get_retry_limiter(destination, clock, store, **kwargs):
|
|||
that will mark the destination as down if an exception is thrown (excluding
|
||||
CodeMessageException with code < 500)
|
||||
|
||||
Args:
|
||||
destination (str): name of homeserver
|
||||
clock (synapse.util.clock): timing source
|
||||
store (synapse.storage.transactions.TransactionStore): datastore
|
||||
ignore_backoff (bool): true to ignore the historical backoff data and
|
||||
try the request anyway. We will still update the next
|
||||
retry_interval on success/failure.
|
||||
|
||||
Example usage:
|
||||
|
||||
try:
|
||||
|
@ -66,7 +75,7 @@ def get_retry_limiter(destination, clock, store, **kwargs):
|
|||
|
||||
now = int(clock.time_msec())
|
||||
|
||||
if retry_last_ts + retry_interval > now:
|
||||
if not ignore_backoff and retry_last_ts + retry_interval > now:
|
||||
raise NotRetryingDestination(
|
||||
retry_last_ts=retry_last_ts,
|
||||
retry_interval=retry_interval,
|
||||
|
@ -124,7 +133,13 @@ class RetryDestinationLimiter(object):
|
|||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
valid_err_code = False
|
||||
if exc_type is not None and issubclass(exc_type, CodeMessageException):
|
||||
if exc_type is None:
|
||||
valid_err_code = True
|
||||
elif not issubclass(exc_type, Exception):
|
||||
# avoid treating exceptions which don't derive from Exception as
|
||||
# failures; this is mostly so as not to catch defer._DefGen.
|
||||
valid_err_code = True
|
||||
elif issubclass(exc_type, CodeMessageException):
|
||||
# Some error codes are perfectly fine for some APIs, whereas other
|
||||
# APIs may expect to never received e.g. a 404. It's important to
|
||||
# handle 404 as some remote servers will return a 404 when the HS
|
||||
|
@ -142,11 +157,13 @@ class RetryDestinationLimiter(object):
|
|||
else:
|
||||
valid_err_code = False
|
||||
|
||||
if exc_type is None or valid_err_code:
|
||||
if valid_err_code:
|
||||
# We connected successfully.
|
||||
if not self.retry_interval:
|
||||
return
|
||||
|
||||
logger.debug("Connection to %s was successful; clearing backoff",
|
||||
self.destination)
|
||||
retry_last_ts = 0
|
||||
self.retry_interval = 0
|
||||
else:
|
||||
|
@ -160,6 +177,10 @@ class RetryDestinationLimiter(object):
|
|||
else:
|
||||
self.retry_interval = self.min_retry_interval
|
||||
|
||||
logger.debug(
|
||||
"Connection to %s was unsuccessful (%s(%s)); backoff now %i",
|
||||
self.destination, exc_type, exc_val, self.retry_interval
|
||||
)
|
||||
retry_last_ts = int(self.clock.time_msec())
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue