Skip to content

Commit

Permalink
tornado: Construct Django BaseHandler once, not per-request.
Browse files Browse the repository at this point in the history
Signed-off-by: Anders Kaseorg <[email protected]>
  • Loading branch information
andersk authored and timabbott committed Sep 30, 2022
1 parent 4c80802 commit 7dcffca
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 9 deletions.
6 changes: 5 additions & 1 deletion zerver/tornado/application.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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",
Expand All @@ -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
Expand Down
20 changes: 12 additions & 8 deletions zerver/tornado/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -111,7 +110,8 @@ async def convert_tornado_request_to_django_request(self) -> HttpRequest:
# `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)

Expand Down Expand Up @@ -156,7 +156,9 @@ async def write_django_response_as_tornado_response(self, response: HttpResponse

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):
Expand Down Expand Up @@ -258,7 +260,9 @@ async def zulip_finish(self, result_dict: Dict[str, Any], old_request: HttpReque
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
Expand Down

0 comments on commit 7dcffca

Please sign in to comment.