[Zodb-checkins] SVN: ZODB/trunk/src/ZEO/StorageServer.py Added a storage tpc_transaction method to get a storage's current

Jim Fulton jim at zope.com
Thu Apr 26 19:19:01 EDT 2007


Log message for revision 74821:
  Added a storage tpc_transaction method to get a storage's current
  transaction, if any.
  
  Treat the undo and version APIs as optional.
  
  Implement loadEx internally, so storages don't have to provide it.
  
  Cache a storage's getTid during setup.
  

Changed:
  U   ZODB/trunk/src/ZEO/StorageServer.py

-=-
Modified: ZODB/trunk/src/ZEO/StorageServer.py
===================================================================
--- ZODB/trunk/src/ZEO/StorageServer.py	2007-04-26 21:19:49 UTC (rev 74820)
+++ ZODB/trunk/src/ZEO/StorageServer.py	2007-04-26 23:19:00 UTC (rev 74821)
@@ -22,11 +22,12 @@
 
 import asyncore
 import cPickle
+import logging
 import os
 import sys
 import threading
 import time
-import logging
+import warnings
 
 import transaction
 
@@ -141,8 +142,8 @@
     def __repr__(self):
         tid = self.transaction and repr(self.transaction.id)
         if self.storage:
-            stid = (self.storage._transaction and
-                    repr(self.storage._transaction.id))
+            stid = (self.tpc_transaction() and
+                    repr(self.tpc_transaction().id))
         else:
             stid = None
         name = self.__class__.__name__
@@ -152,34 +153,64 @@
         log(msg, level=level, label=self.log_label, exc_info=exc_info)
 
     def setup_delegation(self):
-        """Delegate several methods to the storage"""
-        self.versionEmpty = self.storage.versionEmpty
-        self.versions = self.storage.versions
-        self.getSerial = self.storage.getSerial
-        self.history = self.storage.history
-        self.load = self.storage.load
-        self.loadSerial = self.storage.loadSerial
-        self.modifiedInVersion = self.storage.modifiedInVersion
-        record_iternext = getattr(self.storage, 'record_iternext', None)
+        """Delegate several methods to the storage
+        """
+
+        storage = self.storage
+
+        info = self.get_info()
+        if info['supportsVersions']:
+            self.versionEmpty = storage.versionEmpty
+            self.versions = storage.versions
+            self.modifiedInVersion = storage.modifiedInVersion
+        else:
+            self.versionEmpty = lambda version: True
+            self.versions = lambda max=None: ()
+            self.modifiedInVersion = lambda oid: ''
+            def commitVersion(*a, **k):
+                raise NotImplementedError
+            self.commitVersion = self.abortVersion = commitVersion
+
+        if not info['supportsUndo']:
+            self.undoLog = self.undoInfo = lambda *a,**k: ()
+            def undo(*a, **k):
+                raise NotImplementedError
+            self.undo = undo
+
+        self.getTid = storage.getTid
+        self.history = storage.history
+        self.load = storage.load
+        self.loadSerial = storage.loadSerial
+        record_iternext = getattr(storage, 'record_iternext', None)
         if record_iternext is not None:
             self.record_iternext = record_iternext
 
         try:
-            fn = self.storage.getExtensionMethods
+            fn = storage.getExtensionMethods
         except AttributeError:
-            # We must be running with a ZODB which
-            # predates adding getExtensionMethods to
-            # BaseStorage. Eventually this try/except
-            # can be removed
-            pass
+            pass # no extension methods
         else:
             d = fn()
             self._extensions.update(d)
-            for name in d.keys():
+            for name in d:
                 assert not hasattr(self, name)
-                setattr(self, name, getattr(self.storage, name))
-        self.lastTransaction = self.storage.lastTransaction
+                setattr(self, name, getattr(storage, name))
+        self.lastTransaction = storage.lastTransaction
 
+        try:
+            self.tpc_transaction = storage.tpc_transaction
+        except AttributeError:
+            if hasattr(storage, '_transaction'):
+                log("Storage %r doesn't have a tpc_transaction method.\n"
+                    "See ZEO.interfaces.IServeable."
+                    "Falling back to using _transaction attribute, which\n."
+                    "is icky.",
+                    logging.ERROR)
+                self.tpc_transaction = lambda : storage._transaction
+            else:
+                raise
+                
+
     def _check_tid(self, tid, exc=None):
         if self.read_only:
             raise ReadOnlyError()
@@ -240,11 +271,27 @@
                                                                    self)
 
     def get_info(self):
-        return {'length': len(self.storage),
-                'size': self.storage.getSize(),
-                'name': self.storage.getName(),
-                'supportsUndo': self.storage.supportsUndo(),
-                'supportsVersions': self.storage.supportsVersions(),
+        storage = self.storage
+
+        try:
+            supportsVersions = storage.supportsVersions
+        except AttributeError:
+            supportsVersions = False
+        else:
+            supportsVersions = supportsVersions()
+
+        try:
+            supportsUndo = storage.supportsUndo
+        except AttributeError:
+            supportsUndo = False
+        else:
+            supportsUndo = supportsUndo()
+
+        return {'length': len(storage),
+                'size': storage.getSize(),
+                'name': storage.getName(),
+                'supportsUndo': supportsUndo,
+                'supportsVersions': supportsVersions,
                 'extensionMethods': self.getExtensionMethods(),
                 'supports_record_iternext': hasattr(self, 'record_iternext'),
                 }
@@ -259,8 +306,15 @@
 
     def loadEx(self, oid, version):
         self.stats.loads += 1
-        return self.storage.loadEx(oid, version)
+        if version:
+            oversion = self.storage.modifiedInVersion(oid)
+            if oversion == version:
+                data, serial = self.storage.load(oid, version)
+                return data, serial, version
 
+        data, serial = self.storage.load(oid, '')
+        return data, serial, ''
+
     def loadBefore(self, oid, tid):
         self.stats.loads += 1
         return self.storage.loadBefore(oid, tid)
@@ -292,7 +346,7 @@
 
     def verify(self, oid, version, tid):
         try:
-            t = self.storage.getTid(oid)
+            t = self.getTid(oid)
         except KeyError:
             self.client.invalidateVerify((oid, ""))
         else:
@@ -309,7 +363,7 @@
             self.verifying = 1
             self.stats.verifying_clients += 1
         try:
-            os = self.storage.getTid(oid)
+            os = self.getTid(oid)
         except KeyError:
             self.client.invalidateVerify((oid, ''))
             # It's not clear what we should do now.  The KeyError
@@ -624,7 +678,7 @@
     def _wait(self, thunk):
         # Wait for the storage lock to be acquired.
         self._thunk = thunk
-        if self.storage._transaction:
+        if self.tpc_transaction():
             d = Delay()
             self.storage._waiting.append((d, self))
             self.log("Transaction blocked waiting for storage. "



More information about the Zodb-checkins mailing list