[Zodb-checkins] SVN: ZODB/branches/3.9/src/ Bug fixed:

Jim Fulton jim at zope.com
Mon Sep 20 15:22:06 EDT 2010


Log message for revision 116681:
  Bug fixed:
   Process exits or database closes could cause ZEO caches to have
   incorrect data due to a problem in the way invalidations were processed.
  

Changed:
  U   ZODB/branches/3.9/src/CHANGES.txt
  U   ZODB/branches/3.9/src/ZEO/ClientStorage.py
  U   ZODB/branches/3.9/src/ZEO/cache.py
  U   ZODB/branches/3.9/src/ZEO/tests/test_cache.py

-=-
Modified: ZODB/branches/3.9/src/CHANGES.txt
===================================================================
--- ZODB/branches/3.9/src/CHANGES.txt	2010-09-20 19:11:46 UTC (rev 116680)
+++ ZODB/branches/3.9/src/CHANGES.txt	2010-09-20 19:22:06 UTC (rev 116681)
@@ -25,9 +25,10 @@
   invalidation transaction ids matched the cached transaction ids
   should have been ignored.
 
-- Shutting down a process while committing a transaction could cause
-  ZEO client caches to have invalid data.  This, in turn caused stale
-  data to remain in the cache until it was updated.
+- Shutting down a process while committing a transaction or processing
+  invalidations from the server could cause ZEO persistent client
+  caches to have invalid data.  This, in turn caused stale data to
+  remain in the cache until it was updated.
 
 - Conflict errors didn't invalidate ZEO cache entries.
 

Modified: ZODB/branches/3.9/src/ZEO/ClientStorage.py
===================================================================
--- ZODB/branches/3.9/src/ZEO/ClientStorage.py	2010-09-20 19:11:46 UTC (rev 116680)
+++ ZODB/branches/3.9/src/ZEO/ClientStorage.py	2010-09-20 19:22:06 UTC (rev 116681)
@@ -1183,14 +1183,19 @@
         if self._cache is None:
             return
 
+        for oid, _ in self._seriald.iteritems():
+            self._cache.invalidate(oid, tid)
+
         for oid, data in self._tbuf:
-            self._cache.invalidate(oid, tid, False)
             # If data is None, we just invalidate.
             if data is not None:
                 s = self._seriald[oid]
                 if s != ResolvedSerial:
                     assert s == tid, (s, tid)
                     self._cache.store(oid, s, None, data)
+            else:
+                # object deletion
+                self._cache.invalidate(oid, tid)
 
         if self.fshelper is not None:
             blobs = self._tbuf.blobs
@@ -1448,6 +1453,7 @@
             if oid == self._load_oid:
                 self._load_status = 0
             self._cache.invalidate(oid, tid)
+        self._cache.setLastTid(tid)
 
         if self._db is not None:
             self._db.invalidate(tid, oids)

Modified: ZODB/branches/3.9/src/ZEO/cache.py
===================================================================
--- ZODB/branches/3.9/src/ZEO/cache.py	2010-09-20 19:11:46 UTC (rev 116680)
+++ ZODB/branches/3.9/src/ZEO/cache.py	2010-09-20 19:22:06 UTC (rev 116681)
@@ -661,20 +661,13 @@
     # - oid object id
     # - tid the id of the transaction that wrote a new revision of oid,
     #        or None to forget all cached info about oid.
-    # - server_invalidation, a flag indicating whether the
-    #       invalidation has come from the server. It's possible, due
-    #       to threading issues, that when applying a local
-    #       invalidation after a store, that later invalidations from
-    #       the server may already have arrived.
 
     @locked
-    def invalidate(self, oid, tid, server_invalidation=True):
+    def invalidate(self, oid, tid):
         ofs = self.current.get(oid)
         if ofs is None:
             # 0x10 == invalidate (miss)
             self._trace(0x10, oid, tid)
-            if server_invalidation:
-                self.setLastTid(tid)
             return
 
         self.f.seek(ofs)
@@ -701,9 +694,6 @@
             # 0x1C = invalidate (hit, saving non-current)
             self._trace(0x1C, oid, tid)
 
-        if server_invalidation:
-            self.setLastTid(tid)
-
     ##
     # Generates (oid, serial) oairs for all objects in the
     # cache.  This generator is used by cache verification.

Modified: ZODB/branches/3.9/src/ZEO/tests/test_cache.py
===================================================================
--- ZODB/branches/3.9/src/ZEO/tests/test_cache.py	2010-09-20 19:11:46 UTC (rev 116680)
+++ ZODB/branches/3.9/src/ZEO/tests/test_cache.py	2010-09-20 19:22:06 UTC (rev 116681)
@@ -83,9 +83,11 @@
         self.cache.setLastTid(n2)
         self.assertEqual(self.cache.getLastTid(), n2)
         self.assertEqual(self.cache.getLastTid(), n2)
-        self.cache.invalidate(n1, n3)
+        self.cache.setLastTid(n3)
         self.assertEqual(self.cache.getLastTid(), n3)
 
+        # Check that setting tids out of order gives an error:
+
         # the cache complains only when it's non-empty
         self.cache.store(n1, n3, None, 'x')
         self.assertRaises(ValueError, self.cache.setLastTid, n2)



More information about the Zodb-checkins mailing list