Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
2 changes: 2 additions & 0 deletions synapse/api/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ def __init__(
code: int = 429,
retry_after_ms: Optional[int] = None,
errcode: str = Codes.LIMIT_EXCEEDED,
pause: Optional[float] = None,
):
# Use HTTP header Retry-After to enable library-assisted retry handling.
headers = (
Expand All @@ -545,6 +546,7 @@ def __init__(
super().__init__(code, "Too Many Requests", errcode, headers=headers)
self.retry_after_ms = retry_after_ms
self.limiter_name = limiter_name
self.pause = pause

def error_dict(self, config: Optional["HomeServerConfig"]) -> "JsonDict":
return cs_error(self.msg, self.errcode, retry_after_ms=self.retry_after_ms)
Expand Down
4 changes: 1 addition & 3 deletions synapse/api/ratelimiting.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,12 +338,10 @@ async def ratelimit(
)

if not allowed:
if pause:
await self.clock.sleep(pause)

raise LimitExceededError(
limiter_name=self._limiter_name,
retry_after_ms=int(1000 * (time_allowed - time_now_s)),
pause=pause,
)


Expand Down
8 changes: 7 additions & 1 deletion synapse/http/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
from synapse.api.errors import (
CodeMessageException,
Codes,
LimitExceededError,
RedirectException,
SynapseError,
UnrecognizedRequestError,
Expand Down Expand Up @@ -330,7 +331,12 @@ async def _async_render_wrapper(self, request: "SynapseRequest") -> None:
request.request_metrics.name = self.__class__.__name__

with trace_servlet(request, self._extract_context):
callback_return = await self._async_render(request)
try:
callback_return = await self._async_render(request)
except LimitExceededError as e:
if e.pause:
self._clock.sleep(e.pause)
raise

if callback_return is not None:
code, response = callback_return
Expand Down
Loading