Opened 106 minutes ago
Closed 49 minutes ago
#36797 closed New feature (wontfix)
Implement fully async-capable support for django.middleware.common.CommonMiddleware
| Reported by: | Mykhailo Havelia | Owned by: | |
|---|---|---|---|
| Component: | HTTP handling | Version: | 6.0 |
| Severity: | Normal | Keywords: | async |
| Cc: | Mykhailo Havelia | Triage Stage: | Unreviewed |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
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__withoutsync_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_middlewaredecorator
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.
When MiddlewareMixin is eventually removed, we can rename AsyncCommonMiddleware -> CommonMiddleware without breaking changes.
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.
Change History (2)
comment:1 by , 52 minutes ago
comment:2 by , 49 minutes ago
| Resolution: | → wontfix |
|---|---|
| Status: | new → closed |
Hello, Mykhailo,
Thanks for the ticket. Given this is a new feature request, it will have to be proposed and discussed with the community on the new features tracker.
I'll close the ticket for now, but if the community agrees with the proposal, please reopen and reference the issue in the features tracker. For more information, please refer to the documented guidelines for requesting features.