##// END OF EJS Templates
sqlalchemy: enabled connection ping....
marcink -
r1963:64f734c0 default
parent child Browse files
Show More
@@ -40,6 +40,8 b' import uuid'
40 import pygments.lexers
40 import pygments.lexers
41 import sqlalchemy
41 import sqlalchemy
42 import sqlalchemy.engine.url
42 import sqlalchemy.engine.url
43 import sqlalchemy.exc
44 import sqlalchemy.sql
43 import webob
45 import webob
44 import routes.util
46 import routes.util
45
47
@@ -314,6 +316,41 b' def find_calling_context(ignore_modules='
314 return None
316 return None
315
317
316
318
319 def ping_connection(connection, branch):
320 if branch:
321 # "branch" refers to a sub-connection of a connection,
322 # we don't want to bother pinging on these.
323 return
324
325 # turn off "close with result". This flag is only used with
326 # "connectionless" execution, otherwise will be False in any case
327 save_should_close_with_result = connection.should_close_with_result
328 connection.should_close_with_result = False
329
330 try:
331 # run a SELECT 1. use a core select() so that
332 # the SELECT of a scalar value without a table is
333 # appropriately formatted for the backend
334 connection.scalar(sqlalchemy.sql.select([1]))
335 except sqlalchemy.exc.DBAPIError as err:
336 # catch SQLAlchemy's DBAPIError, which is a wrapper
337 # for the DBAPI's exception. It includes a .connection_invalidated
338 # attribute which specifies if this connection is a "disconnect"
339 # condition, which is based on inspection of the original exception
340 # by the dialect in use.
341 if err.connection_invalidated:
342 # run the same SELECT again - the connection will re-validate
343 # itself and establish a new connection. The disconnect detection
344 # here also causes the whole connection pool to be invalidated
345 # so that all stale connections are discarded.
346 connection.scalar(sqlalchemy.sql.select([1]))
347 else:
348 raise
349 finally:
350 # restore "close with result"
351 connection.should_close_with_result = save_should_close_with_result
352
353
317 def engine_from_config(configuration, prefix='sqlalchemy.', **kwargs):
354 def engine_from_config(configuration, prefix='sqlalchemy.', **kwargs):
318 """Custom engine_from_config functions."""
355 """Custom engine_from_config functions."""
319 log = logging.getLogger('sqlalchemy.engine')
356 log = logging.getLogger('sqlalchemy.engine')
@@ -345,6 +382,8 b' def engine_from_config(configuration, pr'
345 parameters, context, executemany):
382 parameters, context, executemany):
346 delattr(conn, 'query_start_time')
383 delattr(conn, 'query_start_time')
347
384
385 sqlalchemy.event.listen(engine, "engine_connect",
386 ping_connection)
348 sqlalchemy.event.listen(engine, "before_cursor_execute",
387 sqlalchemy.event.listen(engine, "before_cursor_execute",
349 before_cursor_execute)
388 before_cursor_execute)
350 sqlalchemy.event.listen(engine, "after_cursor_execute",
389 sqlalchemy.event.listen(engine, "after_cursor_execute",
General Comments 0
You need to be logged in to leave comments. Login now