Add MySQLPingListener() back

The use of wrap_db() to catch low-level problems in the connection
pool appears to be incompatible with new versions of sqlalchemy
(0.7.4/precise).  This re-instates the use of a event listener to
catch the error of 'mysql has gone away'.  Keeps the wrapping
logic in place for use before the connection pool has been constructed,
specifically to allow glance to retry its initial database connection on
service startup.

Fixes bug 967887

Change-Id: Ia732377d3404104b8acf7fe4ada164ec7ecf705f
This commit is contained in:
Adam Gandelman 2012-03-28 17:08:13 -07:00 committed by Brian Waldon
parent 1e708f423c
commit f5ed968136
1 changed files with 27 additions and 8 deletions

View File

@ -27,7 +27,8 @@ import time
import sqlalchemy
from sqlalchemy import asc, create_engine, desc
from sqlalchemy.exc import IntegrityError, OperationalError, DBAPIError
from sqlalchemy.exc import IntegrityError, OperationalError, DBAPIError,\
DisconnectionError
from sqlalchemy.orm import exc
from sqlalchemy.orm import joinedload
from sqlalchemy.orm import sessionmaker
@ -70,6 +71,27 @@ db_opts = [
]
class MySQLPingListener(object):
"""
Ensures that MySQL connections checked out of the
pool are alive.
Borrowed from:
http://groups.google.com/group/sqlalchemy/msg/a4ce563d802c929f
"""
def checkout(self, dbapi_con, con_record, con_proxy):
try:
dbapi_con.cursor().execute('select 1')
except dbapi_con.OperationalError, ex:
if ex.args[0] in (2006, 2013, 2014, 2045, 2055):
logger.warn('Got mysql server has gone away: %s', ex)
raise DisconnectionError("Database server went away")
else:
raise
def configure_db(conf):
"""
Establish the database, create an engine if needed, and
@ -88,9 +110,11 @@ def configure_db(conf):
'echo': False,
'convert_unicode': True
}
if 'mysql' in connection_dict.drivername:
engine_args['listeners'] = [MySQLPingListener()]
try:
_ENGINE = create_engine(sql_connection, **engine_args)
_ENGINE.create = wrap_db_error(_ENGINE.create)
_ENGINE.connect = wrap_db_error(_ENGINE.connect)
_ENGINE.connect()
except Exception, err:
@ -129,12 +153,7 @@ def get_session(autocommit=True, expire_on_commit=False):
_MAKER = sessionmaker(bind=_ENGINE,
autocommit=autocommit,
expire_on_commit=expire_on_commit)
session = _MAKER()
session.query = wrap_db_error(session.query)
session.flush = wrap_db_error(session.flush)
session.execute = wrap_db_error(session.execute)
session.begin = wrap_db_error(session.begin)
return session
return _MAKER()
def is_db_connection_error(args):