#32049 closed Bug (invalid)
Database connection differs between Middleware and views running under ASGI. — at Version 4
Reported by: | Hugo Osvaldo Barrera | Owned by: | nobody |
---|---|---|---|
Component: | HTTP handling | Version: | 3.1 |
Severity: | Normal | Keywords: | ASGI |
Cc: | Andrew Godwin | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
(Was: Middleware behaviour inconsistent between runserver and daphne)
All my views expect a particular middleware to have run (it detects the current tenant based on the request's host).
I'm having an issue which only occurs on production, but I could not reproduce in development mode (even with DEBUG=False
) nor via unit tests.
After just inspecting stack traces, it seems that when handler404
is run, behaviour varies between runserver and daphne.
Looking at the backtrace of my handler404
function:
- When running
django-admin runserver 0.0.0.0:8000
, all my middlewares are in my backtrace, meaning they've gotten executed and the function is called in their context. - When running
daphne myapp.asgi:application --bind 0.0.0.0 --port 8000 --http-timeout 90
, I put a tracepoint in myhandler404
, and the middleware are not in the backtrace. It seems that the view is run outside the context of these middlewares.
I haven't been able to find anything in the docs clarifying whether error handlers should expect middleware to have run successfully, but whatever the intended behaviour is, it should be consistent across the two.
Change History (4)
comment:1 by , 4 years ago
comment:3 by , 4 years ago
Cc: | added |
---|---|
Keywords: | ASGI added |
Resolution: | → invalid |
Status: | new → closed |
This is an interesting one. The issue is the way the ASGIHandler runs your code in separate threads. (The bottom-line will be that what you're trying to do isn't supported: you're going to have to find a thread-safe way of doing this if you want to use ASGI here, now.)
Your middleware sets connection.tenant
in Thread 1. Via the DefaultConnectionProxy
this fetches and sets the property on the "default"
connection for Thread 1.
Your view is then run on Thread 2. Attempting to get connection.tenant
the DefaultConnectionProxy
fetches the "default"
connection for Thread 2.
Since DB connections are not shared between thread, this is not the same connection, so the tenant
attribute you set doesn't exist.
I'll cc Andrew since it's an interesting case, but it's expected behaviour. ASGI/async implies/requires much more thought about what thread you're going to be running on here, and hence how you pass this kind of info around.
comment:4 by , 4 years ago
Description: | modified (diff) |
---|---|
Summary: | Middleware behaviour inconsistent between runserver and daphne → Database connection differs between Middleware and views running under ASGI. |
Hi Hugo. Can you provide a minimal project that reproduces this please?