immutable repairer: fix DownUpConnector so that it satisfies short reads the were requested after the last write and before the close

This is probably the cause of the very rare "loss of progress" bug.  This is tested by unit tests.  A recent patch changed this to errback instead of losing progress, and now this patch is changing it again to return a short read instead of errbacking.  Returning a short read is what the uploader (in encode.py) is expecting, when it is reading the last block of the ciphertext, which might be shorter than the other blocks.
This commit is contained in:
Zooko O'Whielacronx 2009-02-12 17:04:47 -07:00
parent bdb992467c
commit d7dbd6675e

View File

@ -73,16 +73,6 @@ class Repairer(log.PrefixingLogMixin):
return d return d
class PrematureClose(Exception):
# Uploader asked DUC to read a certain number of bytes, and
# Downloader closed DUC before writing enough bytes to satisfy the
# read.
def __init__(self, requested, avail):
self.requested = requested
self.avail = avail
def __repr__(self):
return "<%s requested: %d, avail: %d>" % (self.__class__.__name__, self.requested, self.avail)
class DownUpConnector(log.PrefixingLogMixin): class DownUpConnector(log.PrefixingLogMixin):
implements(IEncryptedUploadable, IDownloadTarget, IConsumer) implements(IEncryptedUploadable, IDownloadTarget, IConsumer)
""" I act like an "encrypted uploadable" -- something that a local uploader can read """ I act like an "encrypted uploadable" -- something that a local uploader can read
@ -186,10 +176,9 @@ class DownUpConnector(log.PrefixingLogMixin):
pass pass
def close(self): def close(self):
self._closed_to_pusher = True self._closed_to_pusher = True
# Any reads which haven't been satisfied by now are not going to be satisfied. # Any reads which haven't been satisfied by now are going to
while self.next_read_ds: # have to be satisfied with short reads.
self.next_read_ds.popleft().errback( self._satisfy_reads_if_possible()
PrematureClose(self.next_read_lens.popleft(), self.bufsiz))
# methods to satisfy the IEncryptedUploader interface # methods to satisfy the IEncryptedUploader interface
# (From the perspective of an uploader I am an IEncryptedUploadable.) # (From the perspective of an uploader I am an IEncryptedUploadable.)