mirror of
https://github.com/zulip/zulip.git
synced 2025-11-06 06:53:25 +00:00
tornado: Call close() on Django HttpResponse objects.
This is necessary to break the uncollectable reference cycle created by our ‘request_notes.saved_response = json_response(…)’, Django’s ‘response._resource_closers.append(request.close)’, and Python’s https://bugs.python.org/issue44680. Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
committed by
Tim Abbott
parent
7cf859882d
commit
fd0ab7c4ec
@@ -148,10 +148,9 @@ class AsyncDjangoHandler(tornado.web.RequestHandler, base.BaseHandler):
|
|||||||
|
|
||||||
def get(self, *args: Any, **kwargs: Any) -> None:
|
def get(self, *args: Any, **kwargs: Any) -> None:
|
||||||
request = self.convert_tornado_request_to_django_request()
|
request = self.convert_tornado_request_to_django_request()
|
||||||
|
|
||||||
try:
|
|
||||||
response = self.get_response(request)
|
response = self.get_response(request)
|
||||||
|
|
||||||
|
try:
|
||||||
if hasattr(response, "asynchronous"):
|
if hasattr(response, "asynchronous"):
|
||||||
# We import async_request_timer_restart during runtime
|
# We import async_request_timer_restart during runtime
|
||||||
# to avoid cyclic dependency with zerver.lib.request
|
# to avoid cyclic dependency with zerver.lib.request
|
||||||
@@ -165,22 +164,21 @@ class AsyncDjangoHandler(tornado.web.RequestHandler, base.BaseHandler):
|
|||||||
# consumed by the request when it eventually returns a
|
# consumed by the request when it eventually returns a
|
||||||
# response and is logged.
|
# response and is logged.
|
||||||
async_request_timer_stop(request)
|
async_request_timer_stop(request)
|
||||||
return
|
else:
|
||||||
finally:
|
|
||||||
# Tell Django that we're done processing this request on
|
|
||||||
# the Django side; this triggers cleanup work like
|
|
||||||
# resetting the urlconf and any cache/database
|
|
||||||
# connections.
|
|
||||||
signals.request_finished.send(sender=self.__class__)
|
|
||||||
|
|
||||||
# For normal/synchronous requests that don't end up
|
# For normal/synchronous requests that don't end up
|
||||||
# long-polling, we fall through to here and just need to write
|
# long-polling, we just need to write the HTTP
|
||||||
# the HTTP response that Django prepared for us via Tornado.
|
# response that Django prepared for us via Tornado.
|
||||||
|
|
||||||
# Mark this handler ID as finished for Zulip's own tracking.
|
# Mark this handler ID as finished for Zulip's own tracking.
|
||||||
clear_handler_by_id(self.handler_id)
|
clear_handler_by_id(self.handler_id)
|
||||||
|
|
||||||
self.write_django_response_as_tornado_response(response)
|
self.write_django_response_as_tornado_response(response)
|
||||||
|
finally:
|
||||||
|
# Tell Django that we're done processing this request on
|
||||||
|
# the Django side; this triggers cleanup work like
|
||||||
|
# resetting the urlconf and any cache/database
|
||||||
|
# connections.
|
||||||
|
response.close()
|
||||||
|
|
||||||
def head(self, *args: Any, **kwargs: Any) -> None:
|
def head(self, *args: Any, **kwargs: Any) -> None:
|
||||||
self.get(*args, **kwargs)
|
self.get(*args, **kwargs)
|
||||||
@@ -258,16 +256,12 @@ class AsyncDjangoHandler(tornado.web.RequestHandler, base.BaseHandler):
|
|||||||
res_type=result_dict["result"], data=result_dict, status=self.get_status()
|
res_type=result_dict["result"], data=result_dict, status=self.get_status()
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
|
||||||
response = self.get_response(request)
|
response = self.get_response(request)
|
||||||
|
try:
|
||||||
# Explicitly mark requests as varying by cookie, since the
|
# Explicitly mark requests as varying by cookie, since the
|
||||||
# middleware will not have seen a session access
|
# middleware will not have seen a session access
|
||||||
patch_vary_headers(response, ("Cookie",))
|
patch_vary_headers(response, ("Cookie",))
|
||||||
|
self.write_django_response_as_tornado_response(response)
|
||||||
finally:
|
finally:
|
||||||
# Tell Django we're done processing this request
|
# Tell Django we're done processing this request
|
||||||
#
|
response.close()
|
||||||
# TODO: Investigate whether this (and other call points in
|
|
||||||
# this file) should be using response.close() instead.
|
|
||||||
signals.request_finished.send(sender=self.__class__)
|
|
||||||
|
|
||||||
self.write_django_response_as_tornado_response(response)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user