Closed
Description
One of the things I've seemed to notice in my app that is deployed via django channels vs. my app that is deployed via gunicorn is that the django channels app seems to persist database connections for some time wheres they open/close for each request in gunicorn.
In both cases I have the Django setting CONN_MAX_AGE set to the default, meaning the db connection should open/close on each request. But it appears django channels ignores this option? If I add the option in, will django channels respect the timeframe given for max age?
Activity
andrewgodwin commentedon May 9, 2016
Are you talking about code deployed as views or as consumers? It's likely we need extra work to make them wrap well around consumers, as they don't have the request started/ended signals, but the view framework should continue to work as it did previously (unless I missed sending a request_close signal)
sachinrekhi commentedon May 9, 2016
aah, got it. Ya it appears that the persisted connections are coming from consumer-related code as opposed to view-related code, which seem to immediately close the connection as per usual.
The reason this came up is I was planning on increasing the value of CONN_MAX_AGE since I want the performance optimization associated with persisted connections. So in terms of prioritizing I'd personally be more interested in ensuring consumers respect long CONN_MAX_AGE values (as opposed to the scenario of ensuring they open/close on each request when CONN_MAX_AGE is set to 0).
andrewgodwin commentedon May 9, 2016
Sure, I suspect we can just hook up similar code to the ones that requests use to achieve this. I'll take a look at it this week,
spearki commentedon May 27, 2016
I'm seeing this cause issues every time we hit the MySQL wait_timeout. Any messages received after the timeout get a "MySQL server has gone away message" and the www worker needs to be restarted before it will process messages again.
At the moment we're handling this with a retry decorator that closes the stale connection. We only close when the exception is raised so this doesn't respect CONN_MAX_AGE either, but you could call close_old_connections() after each call to the consumer instead.
heteddy commentedon Sep 11, 2018
the root cause is that django will close old connections(which has been closed by MySQL) before handing each request and response; while in channels no request trigger close old connections then the database connection will be disconnected by MySQL, so we should do it by yourself;
in channels, before access database
from django.db import close_old_connections close_old_connections