Lift pausing on ratelimited requests to http layer (#18595)
When a request gets ratelimited we (optionally) wait ~500ms before returning to mitigate clients that like to tightloop on request failures. However, this is currently implemented by pausing request processing when we check for ratelimits, which might be deep within request processing, and e.g. while locks are held. Instead, let's hoist the pause to the very top of the HTTP handler. Hopefully, this mitigates the issue where a user sending lots of events to a single room can see their requests time out due to the combination of the linearizer and the pausing of the request. Instead, they should see the requests 429 after ~500ms. The first commit is a refactor to pass the `Clock` to `AsyncResource`, the second commit is the behavioural change.
This commit is contained in:
@@ -316,15 +316,16 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
||||
await self.callback(request)
|
||||
|
||||
def setUp(self) -> None:
|
||||
reactor, _ = get_clock()
|
||||
reactor, clock = get_clock()
|
||||
self.reactor = reactor
|
||||
self.clock = clock
|
||||
|
||||
def test_good_response(self) -> None:
|
||||
async def callback(request: SynapseRequest) -> None:
|
||||
request.write(b"response")
|
||||
request.finish()
|
||||
|
||||
res = WrapHtmlRequestHandlerTests.TestResource()
|
||||
res = WrapHtmlRequestHandlerTests.TestResource(self.clock)
|
||||
res.callback = callback
|
||||
|
||||
channel = make_request(
|
||||
@@ -344,7 +345,7 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
||||
async def callback(request: SynapseRequest, **kwargs: object) -> None:
|
||||
raise RedirectException(b"/look/an/eagle", 301)
|
||||
|
||||
res = WrapHtmlRequestHandlerTests.TestResource()
|
||||
res = WrapHtmlRequestHandlerTests.TestResource(self.clock)
|
||||
res.callback = callback
|
||||
|
||||
channel = make_request(
|
||||
@@ -366,7 +367,7 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
||||
e.cookies.append(b"session=yespls")
|
||||
raise e
|
||||
|
||||
res = WrapHtmlRequestHandlerTests.TestResource()
|
||||
res = WrapHtmlRequestHandlerTests.TestResource(self.clock)
|
||||
res.callback = callback
|
||||
|
||||
channel = make_request(
|
||||
@@ -387,7 +388,7 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
||||
request.write(b"response")
|
||||
request.finish()
|
||||
|
||||
res = WrapHtmlRequestHandlerTests.TestResource()
|
||||
res = WrapHtmlRequestHandlerTests.TestResource(self.clock)
|
||||
res.callback = callback
|
||||
|
||||
channel = make_request(
|
||||
@@ -400,7 +401,7 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
||||
|
||||
class CancellableDirectServeJsonResource(DirectServeJsonResource):
|
||||
def __init__(self, clock: Clock):
|
||||
super().__init__()
|
||||
super().__init__(clock)
|
||||
self.clock = clock
|
||||
|
||||
@cancellable
|
||||
@@ -417,7 +418,7 @@ class CancellableDirectServeHtmlResource(DirectServeHtmlResource):
|
||||
ERROR_TEMPLATE = "{code} {msg}"
|
||||
|
||||
def __init__(self, clock: Clock):
|
||||
super().__init__()
|
||||
super().__init__(clock)
|
||||
self.clock = clock
|
||||
|
||||
@cancellable
|
||||
|
||||
Reference in New Issue
Block a user