Corrected closing of database connections on pool checkin/checkout
authorThierry Florac <thierry.florac@onf.fr>
Wed, 01 Jul 2015 10:17:06 +0200
changeset 11 bd4d9a1f3e8a
parent 10 d775bab6f983
child 12 8faf69f9792f
Corrected closing of database connections on pool checkin/checkout
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]