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

Commit

Permalink
Capture the Deferred for request cancellation in _AsyncResource (#…
Browse files Browse the repository at this point in the history
…12694)

All async request processing goes through `_AsyncResource`, so this is
the only place where a `Deferred` needs to be captured for cancellation.

Unfortunately, the same isn't true for determining whether a request
can be cancelled. Each of `RestServlet`, `BaseFederationServlet`,
`DirectServe{Html,Json}Resource` and `ReplicationEndpoint` have
different wrappers around the method doing the request handling and they
all need to be handled separately.

Signed-off-by: Sean Quah <seanq@element.io>
  • Loading branch information
squahtx authored May 10, 2022
1 parent 29f0670 commit c997bfb
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 5 deletions.
1 change: 1 addition & 0 deletions changelog.d/12694.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Capture the `Deferred` for request cancellation in `_AsyncResource`.
4 changes: 3 additions & 1 deletion synapse/http/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,9 @@ def __init__(self, extract_context: bool = False):

def render(self, request: SynapseRequest) -> int:
"""This gets called by twisted every time someone sends us a request."""
defer.ensureDeferred(self._async_render_wrapper(request))
request.render_deferred = defer.ensureDeferred(
self._async_render_wrapper(request)
)
return NOT_DONE_YET

@wrap_async_request_handler
Expand Down
9 changes: 5 additions & 4 deletions synapse/http/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,12 @@ def __init__(
# we can't yet create the logcontext, as we don't know the method.
self.logcontext: Optional[LoggingContext] = None

# The `Deferred` to cancel if the client disconnects early. Expected to be set
# by `Resource.render`.
# The `Deferred` to cancel if the client disconnects early and
# `is_render_cancellable` is set. Expected to be set by `Resource.render`.
self.render_deferred: Optional["Deferred[None]"] = None
# A boolean indicating whether `_render_deferred` should be cancelled if the
# client disconnects early. Expected to be set during `Resource.render`.
# A boolean indicating whether `render_deferred` should be cancelled if the
# client disconnects early. Expected to be set by the coroutine started by
# `Resource.render`, if rendering is asynchronous.
self.is_render_cancellable = False

global _next_request_seq
Expand Down

0 comments on commit c997bfb

Please sign in to comment.