[Zodb-checkins] SVN: ZODB/branches/jim-thready/src/ZEO/ Fixed a (distributed) threading issue.

Jim Fulton jim at zope.com
Fri Jan 22 17:30:44 EST 2010


Log message for revision 108398:
  Fixed a (distributed) threading issue.
  
  tpc_finish cleared the storage lock before returning.  This meant that
  other clients could commit transactions and send invalidations before
  the return value was sent to the client. With the recent threading fix
  in ClientStorages, getting the tpc_finish result after other
  invalidations are sent leads to deadlock on the client.
  
  Also fixed a bug in handling of undo errors.  There's no oid to
  associate with the error and the oid doesn't really matter.
  
  Also added a delay repr.
  

Changed:
  U   ZODB/branches/jim-thready/src/ZEO/StorageServer.py
  U   ZODB/branches/jim-thready/src/ZEO/zrpc/connection.py

-=-
Modified: ZODB/branches/jim-thready/src/ZEO/StorageServer.py
===================================================================
--- ZODB/branches/jim-thready/src/ZEO/StorageServer.py	2010-01-22 21:04:08 UTC (rev 108397)
+++ ZODB/branches/jim-thready/src/ZEO/StorageServer.py	2010-01-22 22:30:43 UTC (rev 108398)
@@ -43,7 +43,7 @@
 from ZEO.CommitLog import CommitLog
 from ZEO.monitor import StorageStats, StatsServer
 from ZEO.zrpc.server import Dispatcher
-from ZEO.zrpc.connection import ManagedServerConnection, Delay, MTDelay
+from ZEO.zrpc.connection import ManagedServerConnection, Delay, MTDelay, Result
 from ZEO.zrpc.trigger import trigger
 from ZEO.Exceptions import AuthError
 
@@ -51,7 +51,7 @@
 from ZODB.POSException import StorageError, StorageTransactionError
 from ZODB.POSException import TransactionError, ReadOnlyError, ConflictError
 from ZODB.serialize import referencesf
-from ZODB.utils import u64, p64, oid_repr
+from ZODB.utils import oid_repr, p64, u64, z64
 from ZODB.loglevels import BLATHER
 
 
@@ -432,9 +432,8 @@
         # Note that the tid is still current because we still hold the
         # commit lock. We'll relinquish it in _clear_transaction.
         tid = self.storage.lastTransaction()
-        self._clear_transaction()
         # Return the tid, for cache invalidation optimization
-        return tid
+        return Result(tid, self._clear_transaction)
 
     def _invalidate(self, tid):
         if self.invalidated:
@@ -709,7 +708,7 @@
                          logging.ERROR, exc_info=True)
             err = self._marshal_error(err)
             # The exception is reported back as newserial for this oid
-            self.serials.append((oid, err))
+            self.serials.append((z64, err))
         else:
             self.invalidated.extend(oids)
             self.serials.extend((oid, ResolvedSerial) for oid in oids)

Modified: ZODB/branches/jim-thready/src/ZEO/zrpc/connection.py
===================================================================
--- ZODB/branches/jim-thready/src/ZEO/zrpc/connection.py	2010-01-22 21:04:08 UTC (rev 108397)
+++ ZODB/branches/jim-thready/src/ZEO/zrpc/connection.py	2010-01-22 22:30:43 UTC (rev 108398)
@@ -179,10 +179,12 @@
     the mainloop from sending a response.
     """
 
+    msgid = None
+
     def set_sender(self, msgid, send_reply, return_error):
-        self.msgid = msgid
         self.send_reply = send_reply
         self.return_error = return_error
+        self.msgid = msgid
 
     def reply(self, obj):
         self.send_reply(self.msgid, obj)
@@ -193,6 +195,19 @@
         log("Error raised in delayed method", logging.ERROR, exc_info=True)
         self.return_error(self.msgid, 0, *exc_info[:2])
 
+    def __repr__(self):
+        return "Delay(%r)" % self.msgid
+
+class Result(Delay):
+
+    def __init__(self, *args):
+        self.args = args
+
+    def set_sender(self, msgid, send_reply, return_error):
+        reply, callback = self.args
+        send_reply(msgid, reply)
+        callback()
+
 class MTDelay(Delay):
 
     def __init__(self):



More information about the Zodb-checkins mailing list