From 13ce3668ecf643d67f45235240f6f29a87113df7 Mon Sep 17 00:00:00 2001 From: Antoine Humeau Date: Wed, 10 Oct 2018 16:33:05 +0200 Subject: [PATCH] Set the profiler instance on the request, not the middleware Django only instantiates middleware once. This means that if the profiler is set as a middleware instance variable, concurrent requests will mess with each other. Setting the profiler on the request fixes that. --- django_cprofile_middleware/middleware.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/django_cprofile_middleware/middleware.py b/django_cprofile_middleware/middleware.py index c5d0ddd..f84c565 100644 --- a/django_cprofile_middleware/middleware.py +++ b/django_cprofile_middleware/middleware.py @@ -40,16 +40,19 @@ class ProfilerMiddleware(MiddlewareMixin): This is adapted from an example found here: http://www.slideshare.net/zeeg/django-con-high-performance-django-presentation. """ + PROFILER_REQUEST_ATTR_NAME = '_django_cprofile_middleware_profiler' + def can(self, request): return settings.DEBUG and 'prof' in request.GET and \ request.user is not None and request.user.is_staff def process_view(self, request, callback, callback_args, callback_kwargs): if self.can(request): - self.profiler = profile.Profile() + profiler = profile.Profile() + setattr(request, self.PROFILER_REQUEST_ATTR_NAME, profiler) args = (request,) + callback_args try: - return self.profiler.runcall( + return profiler.runcall( callback, *args, **callback_kwargs) except Exception: # we want the process_exception middleware to fire @@ -57,12 +60,13 @@ def process_view(self, request, callback, callback_args, callback_kwargs): return def process_response(self, request, response): - if self.can(request): - self.profiler.create_stats() + if hasattr(request, self.PROFILER_REQUEST_ATTR_NAME): + profiler = getattr(request, self.PROFILER_REQUEST_ATTR_NAME) + profiler.create_stats() if 'download' in request.GET: import marshal - output = marshal.dumps(self.profiler.stats) + output = marshal.dumps(profiler.stats) response = HttpResponse( output, content_type='application/octet-stream') response['Content-Disposition'] = 'attachment;' \ @@ -70,7 +74,7 @@ def process_response(self, request, response): response['Content-Length'] = len(output) else: io = StringIO() - stats = pstats.Stats(self.profiler, stream=io) + stats = pstats.Stats(profiler, stream=io) stats.strip_dirs().sort_stats(request.GET.get('sort', 'time')) stats.print_stats(int(request.GET.get('count', 100)))