Skip to content

MySQL server gone away in Auth middleware #1122

Closed
@jacky15

Description

@jacky15

When I run django-channels after a when with daphne, I have found some error about auth middleware.

ERROR Exception inside application: (2006, 'MySQL server has gone away')

AND it failed at

File "/app/python/lib/python3.6/site-packages/channels/auth.py", line 27, in get_user

I have try to add database_sync_to_async to all the method needs to access to the username , and call close_connection in my own middleware before the auth middleware. But there still comes the error.

It is there a bug in auth middleware?What should I do to avoid this problem?

Activity

andrewgodwin

andrewgodwin commented on Aug 12, 2018

@andrewgodwin
Member

I don't know if there's a bug in the auth middleware with just this level of error - we need versions, full tracebacks, and confirmation that it happens in a fresh example project with steps to reproduce or that sample project - you can see more here: http://channels.readthedocs.io/en/latest/support.html

Without that I'll have to close this.

jacky15

jacky15 commented on Aug 12, 2018

@jacky15
ContributorAuthor

As I deploy my application on a cloud platform, log is out of order. Here comes some traceback logs.(All the client ip addresses are deleted. ) . I hope that will help.

[2018-08-12 17:24:25] daphne: - - [12/Aug/2018:17:24:25] "WSDISCONNECT /project/" - -

[2018-08-12 17:24:26] daphne: res = self._query(query)

[2018-08-12 17:24:26] daphne: File "/app/python/lib/python3.6/site-packages/MySQLdb/connections.py", line 276, in query

[2018-08-12 17:24:26] daphne: File "/app/python/lib/python3.6/site-packages/channels/auth.py", line 143, in resolve_scope

[2018-08-12 17:24:26] daphne: return await asyncio.wait_for(future, timeout=None)

[2018-08-12 17:24:26] daphne: File "/app/python/lib/python3.6/concurrent/futures/thread.py", line 56, in run

[2018-08-12 17:24:26] daphne: user_id = _get_user_session_key(session)

[2018-08-12 17:24:26] daphne: return self._session[key]

[2018-08-12 17:24:26] daphne: File "/app/python/lib/python3.6/site-packages/django/db/models/query.py", line 1179, in _fetch_all

[2018-08-12 17:24:26] daphne: File "/app/python/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute

[2018-08-12 17:24:26] daphne: File "/app/python/lib/python3.6/site-packages/django/db/backends/mysql/base.py", line 71, in execute

[2018-08-12 17:24:26] daphne: raise errorvalue

[2018-08-12 17:24:26] daphne: File "/app/python/lib/python3.6/site-packages/MySQLdb/cursors.py", line 412, in _query

[2018-08-12 17:24:26] daphne: (2006, 'MySQL server has gone away')

[2018-08-12 17:24:40] daphne: - - [12/Aug/2018:17:24:40] "WSCONNECTING /project/" - -

[2018-08-12 17:24:12] daphne: - - [12/Aug/2018:17:24:12] "WSDISCONNECT /project/" - -

[2018-08-12 17:24:25] daphne: - - [12/Aug/2018:17:24:25] "WSCONNECTING /project/" - -

[2018-08-12 17:24:26] daphne: 2018-08-12 17:24:26,345 ERROR Exception inside application: (2006, 'MySQL server has gone away')

[2018-08-12 17:24:26] daphne: File "/app/python/lib/python3.6/site-packages/asgiref/sync.py", line 108, in call

[2018-08-12 17:24:26] daphne: return super().thread_handler(loop, *args, **kwargs)

[2018-08-12 17:24:26] daphne: return self.func(*args, **kwargs)

[2018-08-12 17:24:26] daphne: File "/app/python/lib/python3.6/site-packages/django/utils/functional.py", line 216, in inner

[2018-08-12 17:24:26] daphne: num = len(clone)

[2018-08-12 17:24:26] daphne: return self.cursor.execute(sql, params)

[2018-08-12 17:24:26] daphne: self.errorhandler(self, exc, value)

[2018-08-12 17:24:31] daphne: - - [12/Aug/2018:17:24:31] "WSCONNECTING /project/" - -


In my case, I use the websocket with class AsyncJsonWebsocketConsumer. I found that if a long time no visit to the server , this error will must be triggered and I have to redeploy my application.Maybe @andrewgodwin you can give me some suggestion on this case? Am I using the AsyncJsonWebsocketConsumer class wrong?

pvanagtmaal

pvanagtmaal commented on Aug 12, 2018

@pvanagtmaal
Contributor

@jacky15 This is standard MySQL behaviour. It basically means that database connection has timed out. Regular Django behaviour is to close the connection after every transaction, and the Channels database_sync_to_async normally closes the connection as well. However, as the Channels docs state:

Right now you will need to call close_old_connections() after any database code you call inside a middleware’s scope-setup method to ensure you don’t leak idle database connections. We hope to call this automatically in future versions of Channels.

Could you try calling that function in your custom middleware and see if that helps?

jacky15

jacky15 commented on Aug 13, 2018

@jacky15
ContributorAuthor

OK, I will try this.
But why AuthMiddlewareStack middleware close the connections default?

jacky15

jacky15 commented on Aug 14, 2018

@jacky15
ContributorAuthor

I found the problem caused by I have set the CONN_MAX_AGE in database settings. After I removed this settings, the problem gone away : )
I think we can updated the docs and show the user SHOULD NOT set this value when using AsyncWebsocketConsumer?

pvanagtmaal

pvanagtmaal commented on Aug 14, 2018

@pvanagtmaal
Contributor

@jacky15 I don't think that would be necessary, as it is not Channels specific. You would encounter exactly the same errors in regular Django views. That said, Django does mention it in the docs:

https://docs.djangoproject.com/en/2.1/ref/databases/#persistent-connections

@andrewgodwin I think you may close this issue :)

andrewgodwin

andrewgodwin commented on Aug 14, 2018

@andrewgodwin
Member

Yes, this is just the standard Django connection behaviour outside of requests, sorry! Not much we can do other than document it.

heteddy

heteddy commented on Sep 11, 2018

@heteddy

the root cause is that django will close old connections(which closed by MySql) each request and response; while in django channels no request trigger close old connections then the database connection will be disconnected by MySQL, so we should do it by yourself;

#channels, before access database
from django.db import close_old_connections close_old_connections

sivabalan2410-bot

sivabalan2410-bot commented on Jul 17, 2024

@sivabalan2410-bot

Even though we removed ### CONN_MAX_AGE, the error remains the same. Many blogs suggest using close_old_connections from django.db, but they never specify which file in Django should effectively handle this. If anyone knows, kindly let me know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @andrewgodwin@pvanagtmaal@jacky15@heteddy@sivabalan2410-bot

        Issue actions

          MySQL server gone away in Auth middleware · Issue #1122 · django/channels