[CalendarServer-changes] [14960] twext/trunk/twext/enterprise

source_changes at macosforge.org source_changes at macosforge.org
Mon Jul 13 14:14:28 PDT 2015


Revision: 14960
          http://trac.calendarserver.org//changeset/14960
Author:   cdaboo at apple.com
Date:     2015-07-13 14:14:28 -0700 (Mon, 13 Jul 2015)
Log Message:
-----------
Fix issue with failure to close a DB connection when service is shutdown whilst a txn is connecting.

Modified Paths:
--------------
    twext/trunk/twext/enterprise/adbapi2.py
    twext/trunk/twext/enterprise/test/test_adbapi2.py

Modified: twext/trunk/twext/enterprise/adbapi2.py
===================================================================
--- twext/trunk/twext/enterprise/adbapi2.py	2015-07-13 20:37:57 UTC (rev 14959)
+++ twext/trunk/twext/enterprise/adbapi2.py	2015-07-13 21:14:28 UTC (rev 14960)
@@ -912,6 +912,7 @@
         """
         self._pool = pool
         self._holder = holder
+        self._connection = False
         self._aborted = False
 
 
@@ -924,6 +925,13 @@
         self._aborted = True
         if self._retry is not None:
             self._retry.cancel()
+
+        def _reallyClose():
+            if self._connection:
+                self._connection.close()
+
+        self._holder.submit(_reallyClose)
+
         d = self._holder.stop()
 
         def removeme(ignored):
@@ -1121,7 +1129,10 @@
 
     def _startOneMore(self):
         """
-        Start one more _ConnectedTxn.
+        Start one more L{_ConnectedTxn}. What happens here is that we first create a
+        L{_ConnectingPseudoTxn} to hold a busy slot whilst the connection is starting
+        up. Once the connection is up, we replace the L{_ConnectingPseudoTxn} with the
+        L{_ConnectedTxn} that will do the actual DB work.
         """
         holder = self._createHolder()
         holder.start()
@@ -1132,9 +1143,9 @@
         def initCursor():
             # support threadlevel=1; we can't necessarily cursor() in a
             # different thread than we do transactions in.
-            connection = self.connectionFactory()
-            cursor = connection.cursor()
-            return (connection, cursor)
+            txn._connection = self.connectionFactory()
+            cursor = txn._connection.cursor()
+            return (txn._connection, cursor)
 
         def finishInit((connection, cursor)):
             if txn._aborted:

Modified: twext/trunk/twext/enterprise/test/test_adbapi2.py
===================================================================
--- twext/trunk/twext/enterprise/test/test_adbapi2.py	2015-07-13 20:37:57 UTC (rev 14959)
+++ twext/trunk/twext/enterprise/test/test_adbapi2.py	2015-07-13 21:14:28 UTC (rev 14960)
@@ -334,6 +334,24 @@
         self.assertEquals(holder.stopped, True)
 
 
+    def test_stopServicePseudoTxn(self):
+        """
+        When L{ConnectionPool.stopService} is called with a pending
+        L{_ConnectingPseudoTxn} active, the DB connection being created
+        is closed.
+        """
+        self.pauseHolders()
+        self.createTransaction()
+        stopResult = self.resultOf(self.pool.stopService())
+        self.assertEquals(stopResult, [])
+        self.flushHolders()
+        [holder] = self.holders
+        self.assertEquals(holder.started, True)
+        self.assertEquals(holder.stopped, True)
+        self.assertEquals(len(self.factory.connections), 1)
+        self.assertEquals(self.factory.connections[0].closed, True)
+
+
     def test_stopServiceMidAbort(self):
         """
         When L{ConnectionPool.stopService} is called with deferreds from
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20150713/8fa1ab8e/attachment.html>


More information about the calendarserver-changes mailing list