Rev 6510: Fix bug #1047309. Treat a series of no-bytes-sent as a ECONNRESET failure. in http://bazaar.launchpad.net/~jameinel/bzr/2.5-unending-sendall-1047309
John Arbash Meinel
john at arbash-meinel.com
Fri Sep 7 13:15:33 UTC 2012
At http://bazaar.launchpad.net/~jameinel/bzr/2.5-unending-sendall-1047309
------------------------------------------------------------
revno: 6510
revision-id: john at arbash-meinel.com-20120907131502-q1t9i715sun447di
parent: pqm at pqm.ubuntu.com-20120907110410-fqh06iqg61pknazl
fixes bug: https://launchpad.net/bugs/1047309
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.5-unending-sendall-1047309
timestamp: Fri 2012-09-07 17:15:02 +0400
message:
Fix bug #1047309. Treat a series of no-bytes-sent as a ECONNRESET failure.
-------------- next part --------------
=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py 2012-02-28 04:58:14 +0000
+++ b/bzrlib/osutils.py 2012-09-07 13:15:02 +0000
@@ -2118,6 +2118,12 @@
return b
+# Consider making this configurable, but right now that seems very much YAGNI
+# This is how many 0's we can get in-a-row. If we manage to send some data
+# after a while, this number gets reset.
+_max_no_content_sends = 3
+
+
def send_all(sock, bytes, report_activity=None):
"""Send all bytes on a socket.
@@ -2132,6 +2138,7 @@
Transport._report_activity
"""
sent_total = 0
+ no_content_count = 0
byte_count = len(bytes)
while sent_total < byte_count:
try:
@@ -2140,8 +2147,17 @@
if e.args[0] != errno.EINTR:
raise
else:
+ if sent == 0:
+ no_content_count += 1
+ if no_content_count > _max_no_content_sends:
+ raise IOError(errno.ECONNRESET,
+ 'Sending to %s returned 0 bytes sent %d times in a row'
+ % (sock, no_content_count))
+ else:
+ no_content_count = 0
sent_total += sent
- report_activity(sent, 'write')
+ if report_activity is not None:
+ report_activity(sent, 'write')
def connect_socket(address):
=== modified file 'bzrlib/tests/test_osutils.py'
--- a/bzrlib/tests/test_osutils.py 2012-02-28 04:58:14 +0000
+++ b/bzrlib/tests/test_osutils.py 2012-09-07 13:15:02 +0000
@@ -819,6 +819,44 @@
self.assertEqual(None, osutils.safe_file_id(None))
+
+class TestSendAll(tests.TestCase):
+
+ def test_send_with_no_progress(self):
+ # See https://bugs.launchpad.net/bzr/+bug/1047309
+ # It seems that paramiko can get into a state where it doesn't error,
+ # but it returns 0 bytes sent for requests over and over again.
+ class NoSendingSocket(object):
+ def __init__(self):
+ self.call_count = 0
+ def send(self, bytes):
+ self.call_count += 1
+ if self.call_count > 100:
+ # Prevent the test suite from hanging
+ raise RuntimeError('too many calls')
+ return 0
+ sock = NoSendingSocket()
+ self.assertRaises(IOError, osutils.send_all, sock, 'content')
+
+ def test_send_minimal_progress(self):
+ # Even if we occasionally get 0 bytes sent, we still progress and
+ # finish
+ class SlowSendingSocket(object):
+ def __init__(self):
+ self.call_count = 0
+ def send(self, bytes):
+ self.call_count += 1
+ if self.call_count > 100:
+ # Prevent the test suite from hanging
+ raise RuntimeError('too many calls')
+ if self.call_count % 3 == 0:
+ return 0
+ return 1
+ sock = SlowSendingSocket()
+ osutils.send_all(sock, 'a reasonable amount of content')
+ self.assertEqual(44, sock.call_count)
+
+
class TestPosixFuncs(tests.TestCase):
"""Test that the posix version of normpath returns an appropriate path
when used with 2 leading slashes."""
=== modified file 'doc/en/release-notes/bzr-2.5.txt'
--- a/doc/en/release-notes/bzr-2.5.txt 2012-09-06 12:05:27 +0000
+++ b/doc/en/release-notes/bzr-2.5.txt 2012-09-07 13:15:02 +0000
@@ -39,6 +39,13 @@
extracted texts from the repository. (Just an ordering constraint on how
they consumed the stream.) (John Arbash Meinel, #1046284)
+* ``osutils.send_all`` now detects if we get a series of zero bytes sent,
+ and fails with a ECONNRESET. It seems if paramiko gets disconnected, it
+ will get into a state where it returns 0 bytes sent, but doesn't raise
+ an error. This change allows us to get a couple hiccups of no content
+ sent, but if it is consistent, we will consider it to be a failure.
+ (John Arbash Meinel, #1047309)
+
* Revert use of --no-tty when gpg signing commits. (Jelmer Vernooij, #1014570)
* Some small bug fixes wrt lightweight checkouts and remote repositories.
More information about the bazaar-commits
mailing list