From 7dcffca50eb72e9d05664cb72062e5fee270354c Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Thu, 29 Sep 2022 18:08:23 -0700 Subject: [PATCH] tornado: Construct Django BaseHandler once, not per-request. Signed-off-by: Anders Kaseorg --- zerver/tornado/application.py | 6 +++++- zerver/tornado/handlers.py | 20 ++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/zerver/tornado/application.py b/zerver/tornado/application.py index 439dd5b531..fc8b0c12b6 100644 --- a/zerver/tornado/application.py +++ b/zerver/tornado/application.py @@ -1,5 +1,6 @@ import tornado.web from django.conf import settings +from django.core.handlers.base import BaseHandler from tornado import autoreload from zerver.lib.queue import TornadoQueueClient @@ -12,6 +13,9 @@ def setup_tornado_rabbitmq(queue_client: TornadoQueueClient) -> None: # nocover def create_tornado_application() -> tornado.web.Application: + django_handler = BaseHandler() + django_handler.load_middleware() + urls = ( r"/notify_tornado", r"/json/events", @@ -20,7 +24,7 @@ def create_tornado_application() -> tornado.web.Application: ) return tornado.web.Application( - [(url, AsyncDjangoHandler) for url in urls], + [(url, AsyncDjangoHandler, dict(django_handler=django_handler)) for url in urls], debug=settings.DEBUG, autoreload=False, # Disable Tornado's own request logging, since we have our own diff --git a/zerver/tornado/handlers.py b/zerver/tornado/handlers.py index 5a94daec10..1c3d72d979 100644 --- a/zerver/tornado/handlers.py +++ b/zerver/tornado/handlers.py @@ -77,12 +77,11 @@ def finish_handler(handler_id: int, event_queue_id: str, contents: List[Dict[str ) -class AsyncDjangoHandler(tornado.web.RequestHandler, base.BaseHandler): - def __init__(self, *args: Any, **kwargs: Any) -> None: - super().__init__(*args, **kwargs) +class AsyncDjangoHandler(tornado.web.RequestHandler): + handler_id: int - # Copied from the django.core.handlers.wsgi __init__() method. - self.load_middleware() + def initialize(self, django_handler: base.BaseHandler) -> None: + self.django_handler = django_handler # Prevent Tornado from automatically finishing the request self._auto_finish = False @@ -111,7 +110,8 @@ class AsyncDjangoHandler(tornado.web.RequestHandler, base.BaseHandler): # `get_response()`. set_script_prefix(get_script_name(environ)) await sync_to_async( - lambda: signals.request_started.send(sender=self.__class__), thread_sensitive=True + lambda: signals.request_started.send(sender=self.django_handler.__class__), + thread_sensitive=True, )() self._request = WSGIRequest(environ) @@ -156,7 +156,9 @@ class AsyncDjangoHandler(tornado.web.RequestHandler, base.BaseHandler): async def get(self, *args: Any, **kwargs: Any) -> None: request = await self.convert_tornado_request_to_django_request() - response = await sync_to_async(lambda: self.get_response(request), thread_sensitive=True)() + response = await sync_to_async( + lambda: self.django_handler.get_response(request), thread_sensitive=True + )() try: if isinstance(response, AsynchronousResponse): @@ -258,7 +260,9 @@ class AsyncDjangoHandler(tornado.web.RequestHandler, base.BaseHandler): res_type=result_dict["result"], data=result_dict, status=self.get_status() ) - response = await sync_to_async(lambda: self.get_response(request), thread_sensitive=True)() + response = await sync_to_async( + lambda: self.django_handler.get_response(request), thread_sensitive=True + )() try: # Explicitly mark requests as varying by cookie, since the # middleware will not have seen a session access