Excessive use of asgiref.local and sync_to_async breaks other context local implementations
See original GitHub issueI am writing on behalf of my employer, sentry.io.
I am not sure whether this issue should be filed against Django or asgiref. Starting with Django 3.1, signal handlers for got_request_exception
are executed with the wrong contextvars
context when running as part of an ASGI request. This can be easily demonstrated by wrapping the Django ASGI app in a middleware that stores something on the context, and trying to retreive that same value from that signal handler.
This is how I became aware of Django’s custom context local implementation that is shipped as part of asgiref. I understand why you do the things you do, but consider that this will break a lot of tracing tooling for Python that may only be orthogonal to Django or ASGI. The situation around context locals is already awful enough, it would be terrible if Sentry and tools like it had to implement a codepath specifically for Django 3 applications, or anything that uses asgiref.local.
I can see the following options:
- avoid releasing Django 3.1 with whatever changes just happened that made errorhandlers execute in the wrong
contextvars
context. Considering that Django 3.1 is already in alpha I would at least consider this as a stopgap measure. - modify asgiref.sync_to_async and its inverse to “drive” contextvars if they are available such that contextvars always behave identically to asgiref.local
- drop asgiref.local entirely and swap it out for the
aiocontextvars
package on PyPI, as the primary purpose of implementing asgiref.local from scratch seemed to have been to support Python 3.6. One would still have to implement 2) for this to work, but the advantage here is that aiocontextvars seems to be significantly more popular across frameworks than asgiref.local.
Those options are not mutually exclusive.
Thanks for considering.
Issue Analytics
- State:
- Created 3 years ago
- Comments:25 (25 by maintainers)
I know, we’ll have to work it out on the Django side. I’m tempted to change the requirement to include a
~=3.2
and a>=3.2.8
.(also this might encourage me to finally put the Django test suite as part of tests for asgiref on here)