mutable/publish: don't loop() right away upon DeadReferenceError. Closes #877
authorBrian Warner <warner@lothar.com>
Sat, 2 Jan 2010 22:08:41 +0000 (14:08 -0800)
committerBrian Warner <warner@lothar.com>
Sat, 2 Jan 2010 22:08:41 +0000 (14:08 -0800)
The bug was that a disconnected server could cause us to re-enter the initial
loop() call, sending multiple queries to a single server, provoking an
incorrect UCWE. To fix it, stall the loop() with an eventual.fireEventually()

src/allmydata/mutable/publish.py

index e9b68cd7447b335360a580414704a06e5e67c775..39ed649b91065ea98ca4361603af7f97fd87fa63 100644 (file)
@@ -10,7 +10,7 @@ from allmydata.util import base32, hashutil, mathutil, idlib, log
 from allmydata import hashtree, codec
 from allmydata.storage.server import si_b2a
 from pycryptopp.cipher.aes import AES
-from foolscap.api import eventually
+from foolscap.api import eventually, fireEventually
 
 from common import MODE_WRITE, MODE_CHECK, DictOfSets, \
      UncoordinatedWriteError, NotEnoughServersError
@@ -636,6 +636,8 @@ class Publish:
             d.addCallbacks(self._got_write_answer, self._got_write_error,
                            callbackArgs=(peerid, shnums, started),
                            errbackArgs=(peerid, shnums, started))
+            # tolerate immediate errback, like with DeadReferenceError
+            d.addBoth(fireEventually)
             d.addCallback(self.loop)
             d.addErrback(self._fatal_error)