# HG changeset patch # User Thierry Florac # Date 1435738626 -7200 # Node ID bd4d9a1f3e8a2238e867289ddaae01790c21ad34 # Parent d775bab6f983e0892425668a0474873c2ef22c0c Corrected closing of database connections on pool checkin/checkout diff -r d775bab6f983 -r bd4d9a1f3e8a src/pyams_alchemy/engine.py --- a/src/pyams_alchemy/engine.py Wed Jul 01 10:16:20 2015 +0200 +++ b/src/pyams_alchemy/engine.py Wed Jul 01 10:17:06 2015 +0200 @@ -52,17 +52,35 @@ @listens_for(Pool, 'checkout') -def pool_checkout(connection, record, proxy): - """Pool checkout""" - logger.debug("Setting checkout timestamp for connection {0!r} ({1!r})".format(connection, record)) +def handle_pool_checkout(connection, record, proxy): + """Pool connection checkout + + Called when a connection is retrieved from the pool. + If the connection record is already marked, we remove it from the mapping. + """ with CONNECTIONS_LOCK: + if record in CONNECTIONS_TIMESTAMP: + logger.debug("Removing timestamp for checked-out connection {0!r} ({1!r})".format(connection, record)) + del CONNECTIONS_TIMESTAMP[record] + + +@listens_for(Pool, 'checkin') +def handle_pool_checkin(connection, record): + """Pool connection checkin + + Called when a connection returns to the pool. + We apply a timestamp on the connection record to be able to close it automatically + after 5 minutes without being used. + """ + with CONNECTIONS_LOCK: + logger.debug("Setting inactivity timestamp for checked-in connection {0!r} ({1!r})".format(connection, record)) CONNECTIONS_TIMESTAMP[record] = datetime.utcnow() class ConnectionCleanerThread(Thread): """Background thread used to clean unused database connections - Each connection is referenced in CONNECTION_TIMESTAMPS on checkout and is invalidated + Each connection is referenced in CONNECTION_TIMESTAMPS on checkin and is invalidated if not being used after 5 minutes """ timeout = 300 @@ -73,7 +91,7 @@ for connection, value in list(CONNECTIONS_TIMESTAMP.items()): delta = now - value if delta.total_seconds() > self.timeout: - logger.debug("Detaching unused connection {0!r} from pool".format(connection)) + logger.debug("Invalidating unused connection {0!r} from pool".format(connection)) with CONNECTIONS_LOCK: connection.invalidate() del CONNECTIONS_TIMESTAMP[connection]