Remove unnecessary reactor reference from `_PerHostRatelimiter` (#14842)

Fix up #14812 to avoid introducing a reference to the reactor.

Signed-off-by: Sean Quah <seanq@matrix.org>
This commit is contained in:
Sean Quah 2023-01-16 13:16:19 +00:00 committed by GitHub
parent 7801fd74da
commit a302d3ecf7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 7 additions and 14 deletions

1
changelog.d/14842.bugfix Normal file
View File

@ -0,0 +1 @@
Fix a long-standing bug where Synapse would exhaust the stack when processing many federation requests where the remote homeserver has disconencted early.

View File

@ -310,7 +310,6 @@ class UsernameAvailabilityRestServlet(RestServlet):
self.hs = hs self.hs = hs
self.registration_handler = hs.get_registration_handler() self.registration_handler = hs.get_registration_handler()
self.ratelimiter = FederationRateLimiter( self.ratelimiter = FederationRateLimiter(
hs.get_reactor(),
hs.get_clock(), hs.get_clock(),
FederationRatelimitSettings( FederationRatelimitSettings(
# Time window of 2s # Time window of 2s

View File

@ -768,7 +768,6 @@ class HomeServer(metaclass=abc.ABCMeta):
@cache_in_self @cache_in_self
def get_federation_ratelimiter(self) -> FederationRateLimiter: def get_federation_ratelimiter(self) -> FederationRateLimiter:
return FederationRateLimiter( return FederationRateLimiter(
self.get_reactor(),
self.get_clock(), self.get_clock(),
config=self.config.ratelimiting.rc_federation, config=self.config.ratelimiting.rc_federation,
metrics_name="federation_servlets", metrics_name="federation_servlets",

View File

@ -34,7 +34,6 @@ from prometheus_client.core import Counter
from typing_extensions import ContextManager from typing_extensions import ContextManager
from twisted.internet import defer from twisted.internet import defer
from twisted.internet.interfaces import IReactorTime
from synapse.api.errors import LimitExceededError from synapse.api.errors import LimitExceededError
from synapse.config.ratelimiting import FederationRatelimitSettings from synapse.config.ratelimiting import FederationRatelimitSettings
@ -147,14 +146,12 @@ class FederationRateLimiter:
def __init__( def __init__(
self, self,
reactor: IReactorTime,
clock: Clock, clock: Clock,
config: FederationRatelimitSettings, config: FederationRatelimitSettings,
metrics_name: Optional[str] = None, metrics_name: Optional[str] = None,
): ):
""" """
Args: Args:
reactor
clock clock
config config
metrics_name: The name of the rate limiter so we can differentiate it metrics_name: The name of the rate limiter so we can differentiate it
@ -166,7 +163,7 @@ class FederationRateLimiter:
def new_limiter() -> "_PerHostRatelimiter": def new_limiter() -> "_PerHostRatelimiter":
return _PerHostRatelimiter( return _PerHostRatelimiter(
reactor=reactor, clock=clock, config=config, metrics_name=metrics_name clock=clock, config=config, metrics_name=metrics_name
) )
self.ratelimiters: DefaultDict[ self.ratelimiters: DefaultDict[
@ -197,14 +194,12 @@ class FederationRateLimiter:
class _PerHostRatelimiter: class _PerHostRatelimiter:
def __init__( def __init__(
self, self,
reactor: IReactorTime,
clock: Clock, clock: Clock,
config: FederationRatelimitSettings, config: FederationRatelimitSettings,
metrics_name: Optional[str] = None, metrics_name: Optional[str] = None,
): ):
""" """
Args: Args:
reactor
clock clock
config config
metrics_name: The name of the rate limiter so we can differentiate it metrics_name: The name of the rate limiter so we can differentiate it
@ -212,7 +207,6 @@ class _PerHostRatelimiter:
for this rate limiter. for this rate limiter.
from the rest in the metrics from the rest in the metrics
""" """
self.reactor = reactor
self.clock = clock self.clock = clock
self.metrics_name = metrics_name self.metrics_name = metrics_name
@ -388,4 +382,4 @@ class _PerHostRatelimiter:
except KeyError: except KeyError:
pass pass
self.reactor.callLater(0.0, start_next_request) self.clock.call_later(0.0, start_next_request)

View File

@ -30,7 +30,7 @@ class FederationRateLimiterTestCase(TestCase):
"""A simple test with the default values""" """A simple test with the default values"""
reactor, clock = get_clock() reactor, clock = get_clock()
rc_config = build_rc_config() rc_config = build_rc_config()
ratelimiter = FederationRateLimiter(reactor, clock, rc_config) ratelimiter = FederationRateLimiter(clock, rc_config)
with ratelimiter.ratelimit("testhost") as d1: with ratelimiter.ratelimit("testhost") as d1:
# shouldn't block # shouldn't block
@ -40,7 +40,7 @@ class FederationRateLimiterTestCase(TestCase):
"""Test what happens when we hit the concurrent limit""" """Test what happens when we hit the concurrent limit"""
reactor, clock = get_clock() reactor, clock = get_clock()
rc_config = build_rc_config({"rc_federation": {"concurrent": 2}}) rc_config = build_rc_config({"rc_federation": {"concurrent": 2}})
ratelimiter = FederationRateLimiter(reactor, clock, rc_config) ratelimiter = FederationRateLimiter(clock, rc_config)
with ratelimiter.ratelimit("testhost") as d1: with ratelimiter.ratelimit("testhost") as d1:
# shouldn't block # shouldn't block
@ -67,7 +67,7 @@ class FederationRateLimiterTestCase(TestCase):
rc_config = build_rc_config( rc_config = build_rc_config(
{"rc_federation": {"sleep_limit": 2, "sleep_delay": 500}} {"rc_federation": {"sleep_limit": 2, "sleep_delay": 500}}
) )
ratelimiter = FederationRateLimiter(reactor, clock, rc_config) ratelimiter = FederationRateLimiter(clock, rc_config)
with ratelimiter.ratelimit("testhost") as d1: with ratelimiter.ratelimit("testhost") as d1:
# shouldn't block # shouldn't block
@ -98,7 +98,7 @@ class FederationRateLimiterTestCase(TestCase):
} }
} }
) )
ratelimiter = FederationRateLimiter(reactor, clock, rc_config) ratelimiter = FederationRateLimiter(clock, rc_config)
with ratelimiter.ratelimit("testhost") as d: with ratelimiter.ratelimit("testhost") as d:
# shouldn't block # shouldn't block