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

Commit 5cfb004

Browse files
authored
Add ability to cancel disconnected requests to SynapseRequest (#12588)
Signed-off-by: Sean Quah <[email protected]>
1 parent 5c00151 commit 5cfb004

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

changelog.d/12588.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add ability to cancel disconnected requests to `SynapseRequest`.

synapse/http/site.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import attr
2020
from zope.interface import implementer
2121

22+
from twisted.internet.defer import Deferred
2223
from twisted.internet.interfaces import IAddress, IReactorTime
2324
from twisted.python.failure import Failure
2425
from twisted.web.http import HTTPChannel
@@ -91,6 +92,13 @@ def __init__(
9192
# we can't yet create the logcontext, as we don't know the method.
9293
self.logcontext: Optional[LoggingContext] = None
9394

95+
# The `Deferred` to cancel if the client disconnects early. Expected to be set
96+
# by `Resource.render`.
97+
self.render_deferred: Optional["Deferred[None]"] = None
98+
# A boolean indicating whether `_render_deferred` should be cancelled if the
99+
# client disconnects early. Expected to be set during `Resource.render`.
100+
self.is_render_cancellable = False
101+
94102
global _next_request_seq
95103
self.request_seq = _next_request_seq
96104
_next_request_seq += 1
@@ -357,7 +365,21 @@ def connectionLost(self, reason: Union[Failure, Exception]) -> None:
357365
{"event": "client connection lost", "reason": str(reason.value)}
358366
)
359367

360-
if not self._is_processing:
368+
if self._is_processing:
369+
if self.is_render_cancellable:
370+
if self.render_deferred is not None:
371+
# Throw a cancellation into the request processing, in the hope
372+
# that it will finish up sooner than it normally would.
373+
# The `self.processing()` context manager will call
374+
# `_finished_processing()` when done.
375+
with PreserveLoggingContext():
376+
self.render_deferred.cancel()
377+
else:
378+
logger.error(
379+
"Connection from client lost, but have no Deferred to "
380+
"cancel even though the request is marked as cancellable."
381+
)
382+
else:
361383
self._finished_processing()
362384

363385
def _started_processing(self, servlet_name: str) -> None:

0 commit comments

Comments
 (0)