[Zodb-checkins] CVS: ZODB3/ZEO - StorageServer.py:1.64

Guido van Rossum guido@python.org
Tue, 17 Sep 2002 14:33:33 -0400


Update of /cvs-repository/ZODB3/ZEO
In directory cvs.zope.org:/tmp/cvs-serv32273

Modified Files:
	StorageServer.py 
Log Message:
Change how a disconnect in mid-transaction is handled.  Rather than
trying to fake a tpc_abort() call with the right transaction id, call
a new method abort(), which resets some instance variables and then
calls the strategy's abort() method.  The immediate strategy's abort()
aborts its own transaction and then calls the zeo_storage's
handle_waiting() method to restart the next blocked transaction from
the _waiting list; the delayed strategy's abort() removes the
zeo_storage from the _waiting list.


=== ZODB3/ZEO/StorageServer.py 1.63 => 1.64 ===
--- ZODB3/ZEO/StorageServer.py:1.63	Tue Sep 17 14:08:43 2002
+++ ZODB3/ZEO/StorageServer.py	Tue Sep 17 14:33:32 2002
@@ -134,7 +134,7 @@
         # any pending transaction.  Not sure if this is the cleanest way.
         if self.transaction is not None:
             self.log("disconnected during transaction %s" % self.transaction)
-            self.tpc_abort(self.transaction.id)
+            self.abort()
         else:
             self.log("disconnected")
 
@@ -329,15 +329,13 @@
         strategy.tpc_abort()
         self.transaction = None
         self.strategy = None
-        # When ZEOStorage.notifyDisconnected() calls self.tpc_abort(),
-        # it is possible that self.strategy is DelayedCommitStrategy.
-        # In that case, ZEOStorage.tpc_abort() should *not* call
-        # self.handle_waiting(), otherwise there could be two
-        # ZEOStorage instances whose strategy is
-        # ImmediateCommitStrategy!
-        if isinstance(strategy, ImmediateCommitStrategy):
-            self.handle_waiting()
-        # XXX else, should we remove ourselves from storage._waiting???
+        self.handle_waiting()
+
+    def abort(self):
+        strategy = self.strategy
+        self.transaction = None
+        self.strategy = None
+        strategy.abort(self)
 
     # XXX handle new serialnos
 
@@ -459,6 +457,9 @@
 
     def tpc_finish(self): pass
 
+    # What to do if a connection is closed in mid-transaction
+    def abort(self, zeo_storage): pass
+
 class ImmediateCommitStrategy:
     """The storage is available so do a normal commit."""
 
@@ -533,6 +534,10 @@
         self.invalidated.extend(inv)
         return oids
 
+    def abort(self, zeo_storage):
+        self.tpc_abort()
+        zeo_storage.handle_waiting()
+
 class DelayedCommitStrategy:
     """The storage is unavailable, so log to a file."""
 
@@ -595,6 +600,15 @@
             new_strategy.store(oid, serial, data, version)
         meth = getattr(new_strategy, self.name)
         return meth(*self.args)
+
+    def abort(self, zeo_storage):
+        # Delete (d, zeo_storage) from the _waiting list, if found.
+        waiting = self.storage._waiting
+        for i in range(len(waiting)):
+            d, z = waiting[i]
+            if z is zeo_storage:
+                del waiting[i]
+                break
 
 def run_in_thread(method, *args):
     t = SlowMethodThread(method, args)