Code of Conduct
Feature Description
Django currently ships all its built-in middleware as synchronous MiddlewareMixin, which forces the entire request stack through sync_to_async, preventing users from achieving a fully asynchronous request flow. To enable a true async pathway, Django needs async-capable versions of these middlewares without breaking existing custom middleware that subclasses them.
Problem
From the Django documentation:
You will only get the benefits of a fully asynchronous request stack if you have no synchronous middleware loaded into your site.
Currently, all of Django's internal middleware uses MiddlewareMixin and relies on sync_to_async under the hood. This makes it difficult for end users to have a fully async request flow, because they would need to copy and adapt all internal logic for each middleware, and maintain it across Django releases.
Some internal middleware only performs CPU-bound operations and does not require async/AIO logic, so it could safely be used in both sync and async contexts without sync_to_async.
Options to solve this:
- Implement
__acall__ without sync_to_async
Not recommended. Can lead to subtle bugs if users subclass and customize the middleware:
class CustomCommonMiddleware(CommonMiddleware):
def process_response(self, request, response):
# custom logic
return super().process_response(request, response)
In an async context, this custom logic would be ignored or behave unexpectedly.
- Rewrite middlewares using
sync_and_async_middleware decorator
Safe and straightforward. Breaking change: would break all existing custom middleware that inherits from the internal middleware.
- Implement separate async middleware (
AsyncCommonMiddleware)
Compromise solution. Safe for users: they can explicitly replace CommonMiddleware with AsyncCommonMiddleware in async setups.
I'm going to start by implementing an async version of CommonMiddleware as a test case for this approach. Once we validate it, the plan is to extend the same pattern to:
- django.contrib.auth.middleware.AuthenticationMiddleware
- django.middleware.locale.LocaleMiddleware
- django.middleware.security.SecurityMiddleware
If you have any thoughts or concerns about this approach, especially regarding edge cases or backward compatibility, please share them.
Request or proposal
proposal
Additional Details
No response
Implementation Suggestions
MR with example https://github.com/Arfey/django/pull/4/files
Code of Conduct
Feature Description
Django currently ships all its built-in middleware as synchronous MiddlewareMixin, which forces the entire request stack through sync_to_async, preventing users from achieving a fully asynchronous request flow. To enable a true async pathway, Django needs async-capable versions of these middlewares without breaking existing custom middleware that subclasses them.
Problem
From the Django documentation:
You will only get the benefits of a fully asynchronous request stack if you have no synchronous middleware loaded into your site.
Currently, all of Django's internal middleware uses
MiddlewareMixinand relies onsync_to_asyncunder the hood. This makes it difficult for end users to have a fully async request flow, because they would need to copy and adapt all internal logic for each middleware, and maintain it across Django releases.Some internal middleware only performs
CPU-bound operations and does not requireasync/AIOlogic, so it could safely be used in bothsyncandasynccontexts withoutsync_to_async.Options to solve this:
__acall__withoutsync_to_asyncNot recommended. Can lead to subtle bugs if users subclass and customize the middleware:
In an async context, this custom logic would be ignored or behave unexpectedly.
sync_and_async_middlewaredecoratorSafe and straightforward. Breaking change: would break all existing custom middleware that inherits from the internal middleware.
AsyncCommonMiddleware)Compromise solution. Safe for users: they can explicitly replace
CommonMiddlewarewithAsyncCommonMiddlewarein async setups.I'm going to start by implementing an async version of
CommonMiddlewareas a test case for this approach. Once we validate it, the plan is to extend the same pattern to:If you have any thoughts or concerns about this approach, especially regarding edge cases or backward compatibility, please share them.
Request or proposal
proposal
Additional Details
No response
Implementation Suggestions
MR with example https://github.com/Arfey/django/pull/4/files