Skip to content

Commit c401513

Browse files
authored
Async compatible HistoryPanel (#1991)
* async compatible history panel * Update debug_toolbar/toolbar.py
1 parent 423ad36 commit c401513

File tree

4 files changed

+32
-8
lines changed

4 files changed

+32
-8
lines changed

debug_toolbar/panels/history/panel.py

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
class HistoryPanel(Panel):
1717
"""A panel to display History"""
1818

19+
is_async = True
1920
title = _("History")
2021
nav_title = _("History")
2122
template = "debug_toolbar/panels/history.html"

debug_toolbar/toolbar.py

+13-6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from django.apps import apps
1313
from django.conf import settings
1414
from django.core.exceptions import ImproperlyConfigured
15+
from django.core.handlers.asgi import ASGIRequest
1516
from django.dispatch import Signal
1617
from django.template import TemplateSyntaxError
1718
from django.template.loader import render_to_string
@@ -101,12 +102,18 @@ def should_render_panels(self):
101102
If False, the panels will be loaded via Ajax.
102103
"""
103104
if (render_panels := self.config["RENDER_PANELS"]) is None:
104-
# If wsgi.multiprocess isn't in the headers, then it's likely
105-
# being served by ASGI. This type of set up is most likely
106-
# incompatible with the toolbar until
107-
# https://github.com/jazzband/django-debug-toolbar/issues/1430
108-
# is resolved.
109-
render_panels = self.request.META.get("wsgi.multiprocess", True)
105+
# If wsgi.multiprocess is true then it is either being served
106+
# from ASGI or multithreaded third-party WSGI server eg gunicorn.
107+
# we need to make special check for ASGI for supporting
108+
# async context based requests.
109+
if isinstance(self.request, ASGIRequest):
110+
render_panels = False
111+
else:
112+
# The wsgi.multiprocess case of being True isn't supported until the
113+
# toolbar has resolved the following issue:
114+
# This type of set up is most likely
115+
# https://github.com/jazzband/django-debug-toolbar/issues/1430
116+
render_panels = self.request.META.get("wsgi.multiprocess", True)
110117
return render_panels
111118

112119
# Handle storing toolbars in memory and fetching them later on

docs/architecture.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ Problematic Parts
8282
- Support for async and multi-threading: ``debug_toolbar.middleware.DebugToolbarMiddleware``
8383
is now async compatible and can process async requests. However certain
8484
panels such as ``SQLPanel``, ``TimerPanel``,
85-
``RequestPanel``, ``HistoryPanel`` and ``ProfilingPanel`` aren't fully
85+
``RequestPanel`` and ``ProfilingPanel`` aren't fully
8686
compatible and currently being worked on. For now, these panels
8787
are disabled by default when running in async environment.
8888
follow the progress of this issue in `Async compatible toolbar project <https://github.com/orgs/jazzband/projects/9>`_.

tests/test_integration.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from django.db import connection
1212
from django.http import HttpResponse
1313
from django.template.loader import get_template
14-
from django.test import RequestFactory
14+
from django.test import AsyncRequestFactory, RequestFactory
1515
from django.test.utils import override_settings
1616

1717
from debug_toolbar.forms import SignedDataForm
@@ -126,6 +126,22 @@ def test_should_render_panels_multiprocess(self):
126126
request.META.pop("wsgi.multiprocess")
127127
self.assertTrue(toolbar.should_render_panels())
128128

129+
def test_should_render_panels_asgi(self):
130+
"""
131+
The toolbar not should render the panels on each request when wsgi.multiprocess
132+
is True or missing in case of async context rather than multithreaded
133+
wsgi.
134+
"""
135+
async_request = AsyncRequestFactory().get("/")
136+
# by default ASGIRequest will have wsgi.multiprocess set to True
137+
# but we are still assigning this to true cause this could change
138+
# and we specifically need to check that method returns false even with
139+
# wsgi.multiprocess set to true
140+
async_request.META["wsgi.multiprocess"] = True
141+
toolbar = DebugToolbar(async_request, self.get_response)
142+
toolbar.config["RENDER_PANELS"] = None
143+
self.assertFalse(toolbar.should_render_panels())
144+
129145
def _resolve_stats(self, path):
130146
# takes stats from Request panel
131147
request = rf.get(path)

0 commit comments

Comments
 (0)