[Zodb-checkins] SVN: ZODB/branches/3.6/ - Changed the automatic garbage collection when opening a connection to only

Christian Theune ct at gocept.com
Wed Jun 6 12:21:06 EDT 2007


Log message for revision 76435:
  - Changed the automatic garbage collection when opening a connection to only
    apply the garbage collections on those connections in the pool that are
    closed. (This fixed issue 113932.)
  

Changed:
  U   ZODB/branches/3.6/NEWS.txt
  U   ZODB/branches/3.6/src/ZODB/DB.py
  U   ZODB/branches/3.6/src/ZODB/tests/test_cache.py

-=-
Modified: ZODB/branches/3.6/NEWS.txt
===================================================================
--- ZODB/branches/3.6/NEWS.txt	2007-06-06 16:14:22 UTC (rev 76434)
+++ ZODB/branches/3.6/NEWS.txt	2007-06-06 16:21:05 UTC (rev 76435)
@@ -103,6 +103,10 @@
   and/or store limited resources (such as RDB connections) in connection
   caches may benefit.
 
+- Changed the automatic garbage collection when opening a connection to only
+  apply the garbage collections on those connections in the pool that are
+  closed. (This fixed issue 113932.)
+
 ZEO
 ---
 

Modified: ZODB/branches/3.6/src/ZODB/DB.py
===================================================================
--- ZODB/branches/3.6/src/ZODB/DB.py	2007-06-06 16:14:22 UTC (rev 76434)
+++ ZODB/branches/3.6/src/ZODB/DB.py	2007-06-06 16:21:05 UTC (rev 76435)
@@ -145,10 +145,18 @@
             assert result in self.all
         return result
 
-    # For every live connection c, invoke f(c).
-    def map(self, f):
-        self.all.map(f)
+    def map(self, f, open_connections=True):
+        """For every live connection c, invoke f(c).
 
+        If `open_connections` is false then only call f(c) on closed
+        connections.
+
+        """
+        if open_connections:
+            self.all.map(f)
+        else:
+            map(f, self.available)
+
 class DB(object):
     """The Object Database
     -------------------
@@ -304,12 +312,17 @@
         finally:
             self._r()
 
-    # Call f(c) for all connections c in all pools in all versions.
-    def _connectionMap(self, f):
+    def _connectionMap(self, f, open_connections=True):
+        """Call f(c) for all connections c in all pools in all versions.
+
+        If `open_connections` is false then f(c) is only called on closed
+        connections.
+
+        """
         self._a()
         try:
             for pool in self._pools.values():
-                pool.map(f)
+                pool.map(f, open_connections=open_connections)
         finally:
             self._r()
 
@@ -542,7 +555,7 @@
             result.open(transaction_manager, mvcc, synch)
 
             # A good time to do some cache cleanup.
-            self._connectionMap(lambda c: c.cacheGC())
+            self._connectionMap(lambda c: c.cacheGC(), open_connections=False)
 
             return result
 

Modified: ZODB/branches/3.6/src/ZODB/tests/test_cache.py
===================================================================
--- ZODB/branches/3.6/src/ZODB/tests/test_cache.py	2007-06-06 16:14:22 UTC (rev 76434)
+++ ZODB/branches/3.6/src/ZODB/tests/test_cache.py	2007-06-06 16:21:05 UTC (rev 76435)
@@ -51,6 +51,9 @@
 
     init = classmethod(init)
 
+class PersistentObject(Persistent):
+    pass
+
 class CacheTests:
 
     def test_cache(self):
@@ -204,6 +207,35 @@
         4
         """
 
+    def test_gc_on_open_connections(self):
+        r"""Test that automatic GC is not applied to open connections.
 
+        This test (and the corresponding fix) was introduced because of bug
+        report 113923.
+
+        We start with a persistent object and add a list attribute::
+
+            >>> db = databaseFromString("<zodb>\n"
+            ...                         "cache-size 0\n"
+            ...                         "<mappingstorage/>\n"
+            ...                         "</zodb>")
+            >>> cn1 = db.open()
+            >>> r = cn1.root()
+            >>> r['ob'] = PersistentObject()
+            >>> r['ob'].l = []
+            >>> transaction.commit()
+
+        Now, let's modify the object in a way that doesn't get noticed. Then,
+        we open another connection which triggers automatic garbage
+        connection. After that, the object should not have been ghostified::
+
+            >>> r['ob'].l.append(1)
+            >>> cn2 = db.open()
+            >>> r['ob'].l
+            [1]
+
+        """
+
+
 def test_suite():
     return doctest.DocTestSuite()



More information about the Zodb-checkins mailing list