[Checkins] SVN: Sandbox/wichert/ZODB38-jarn/ Merge Shane Hathaway's poll-invalidation patch

Wichert Akkerman wichert at wiggy.net
Mon Sep 22 13:25:49 EDT 2008


Log message for revision 91364:
  Merge Shane Hathaway's poll-invalidation patch

Changed:
  U   Sandbox/wichert/ZODB38-jarn/NEWS.txt
  U   Sandbox/wichert/ZODB38-jarn/src/ZODB/Connection.py
  U   Sandbox/wichert/ZODB38-jarn/src/ZODB/DB.py

-=-
Modified: Sandbox/wichert/ZODB38-jarn/NEWS.txt
===================================================================
--- Sandbox/wichert/ZODB38-jarn/NEWS.txt	2008-09-22 17:17:25 UTC (rev 91363)
+++ Sandbox/wichert/ZODB38-jarn/NEWS.txt	2008-09-22 17:25:49 UTC (rev 91364)
@@ -1,8 +1,11 @@
 Whats different in this branch
+==============================
 
 - Merged Dieter Mauer's object-size-based object cache branch 
 
+- Merged Shane Hathaway's poll-invalidation patch, as needed for RelStorage
 
+
 Whats new in ZODB 3.8.1
 =======================
 

Modified: Sandbox/wichert/ZODB38-jarn/src/ZODB/Connection.py
===================================================================
--- Sandbox/wichert/ZODB38-jarn/src/ZODB/Connection.py	2008-09-22 17:17:25 UTC (rev 91363)
+++ Sandbox/wichert/ZODB38-jarn/src/ZODB/Connection.py	2008-09-22 17:25:49 UTC (rev 91364)
@@ -90,8 +90,14 @@
         self.connections = {self._db.database_name: self}
 
         self._version = version
-        self._normal_storage = self._storage = db._storage
-        self.new_oid = db._storage.new_oid
+        storage = db._storage
+        m = getattr(storage, 'bind_connection', None)
+        if m is not None:
+            # Use a storage instance bound to this connection.
+            storage = m(self)
+
+        self._normal_storage = self._storage = storage
+        self.new_oid = storage.new_oid
         self._savepoint_storage = None
 
         # Do we need to join a txn manager?
@@ -151,6 +157,12 @@
         # in the cache on abort and in other connections on finish.
         self._modified = []
 
+        # Allow the storage to decide whether invalidations should
+        # propagate between connections.  If the storage provides MVCC
+        # semantics, it is better to not propagate invalidations between
+        # connections.
+        self._propagate_invalidations = getattr(
+            self._storage, 'propagate_invalidations', True)
 
         # _invalidated queues invalidate messages delivered from the DB
         # _inv_lock prevents one thread from modifying the set while
@@ -297,6 +309,11 @@
         if self._opened:
             self.transaction_manager.unregisterSynch(self)
 
+        # If the storage wants to know, tell it this connection is closing.
+        m = getattr(self._storage, 'connection_closing', None)
+        if m is not None:
+            m()
+
         if primary:
             for connection in self.connections.values():
                 if connection is not self:
@@ -328,6 +345,10 @@
 
     def invalidate(self, tid, oids):
         """Notify the Connection that transaction 'tid' invalidated oids."""
+        if not self._propagate_invalidations:
+            # The storage disabled inter-connection invalidation.
+            return
+
         self._inv_lock.acquire()
         try:
             if self._txn_time is None:
@@ -469,8 +490,23 @@
         self._registered_objects = []
         self._creating.clear()
 
+    def _poll_invalidations(self):
+        """Poll and process object invalidations provided by the storage.
+        """
+        m = getattr(self._storage, 'poll_invalidations', None)
+        if m is not None:
+            # Poll the storage for invalidations.
+            invalidated = m()
+            if invalidated is None:
+                # special value: the transaction is so old that
+                # we need to flush the whole cache.
+                self._cache.invalidate(self._cache.cache_data.keys())
+            elif invalidated:
+                self._cache.invalidate(invalidated)
+
     # Process pending invalidations.
     def _flush_invalidations(self):
+        self._poll_invalidations()
         self._inv_lock.acquire()
         try:
             # Non-ghostifiable objects may need to read when they are

Modified: Sandbox/wichert/ZODB38-jarn/src/ZODB/DB.py
===================================================================
--- Sandbox/wichert/ZODB38-jarn/src/ZODB/DB.py	2008-09-22 17:17:25 UTC (rev 91363)
+++ Sandbox/wichert/ZODB38-jarn/src/ZODB/DB.py	2008-09-22 17:25:49 UTC (rev 91364)
@@ -291,6 +291,10 @@
             storage.store(z64, None, file.getvalue(), '', t)
             storage.tpc_vote(t)
             storage.tpc_finish(t)
+        if hasattr(storage, 'connection_closing'):
+            # Let the storage release whatever resources it used for loading
+            # the root object.
+            storage.connection_closing()
 
         # Multi-database setup.
         if databases is None:



More information about the Checkins mailing list