Rev 6511: Push the change down into osutils.send_all. Needs tests at that level. in http://bazaar.launchpad.net/~jameinel/bzr/2.5-conn-reset-socket-pipe-1047325

John Arbash Meinel john at arbash-meinel.com
Mon Sep 10 11:50:43 UTC 2012


At http://bazaar.launchpad.net/~jameinel/bzr/2.5-conn-reset-socket-pipe-1047325

------------------------------------------------------------
revno: 6511
revision-id: john at arbash-meinel.com-20120910115034-w5vgbm4o3ham01l1
parent: john at arbash-meinel.com-20120907123818-tq2qsh7gum6aixjx
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.5-conn-reset-socket-pipe-1047325
timestamp: Mon 2012-09-10 15:50:34 +0400
message:
  Push the change down into osutils.send_all. Needs tests at that level.
-------------- next part --------------
=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py	2012-02-28 04:58:14 +0000
+++ b/bzrlib/osutils.py	2012-09-10 11:50:34 +0000
@@ -2064,7 +2064,7 @@
 # data at once.
 MAX_SOCKET_CHUNK = 64 * 1024
 
-_end_of_stream_errors = [errno.ECONNRESET]
+_end_of_stream_errors = [errno.ECONNRESET, errno.EPIPE, errno.EINVAL]
 for _eno in ['WSAECONNRESET', 'WSAECONNABORTED']:
     _eno = getattr(errno, _eno, None)
     if _eno is not None:
@@ -2136,7 +2136,10 @@
     while sent_total < byte_count:
         try:
             sent = sock.send(buffer(bytes, sent_total, MAX_SOCKET_CHUNK))
-        except socket.error, e:
+        except (socket.error, IOError), e:
+            if e.args[0] in _end_of_stream_errors:
+                raise errors.ConnectionReset(
+                    "Error trying to write to socket", e)
             if e.args[0] != errno.EINTR:
                 raise
         else:

=== modified file 'bzrlib/smart/medium.py'
--- a/bzrlib/smart/medium.py	2012-09-07 12:38:18 +0000
+++ b/bzrlib/smart/medium.py	2012-09-10 11:50:34 +0000
@@ -910,7 +910,7 @@
         except IOError, e:
             if e.errno in (errno.EINVAL, errno.EPIPE):
                 raise errors.ConnectionReset(
-                    "Error trying to write to subprocess:\n%s" % (e,))
+                    "Error trying to write to subprocess", e)
             raise
         self._report_activity(len(bytes), 'write')
 
@@ -1043,7 +1043,7 @@
 
 class SmartClientSocketMedium(SmartClientStreamMedium):
     """A client medium using a socket.
-    
+
     This class isn't usable directly.  Use one of its subclasses instead.
     """
 
@@ -1055,13 +1055,7 @@
     def _accept_bytes(self, bytes):
         """See SmartClientMedium.accept_bytes."""
         self._ensure_connection()
-        try:
-            osutils.send_all(self._socket, bytes, self._report_activity)
-        except (OSError, IOError, socket.error), e:
-            if e.errno in (errno.EINVAL, errno.EPIPE, errno.ECONNRESET):
-                raise errors.ConnectionReset(
-                    "Error trying to write to socket:\n%s" % (e,))
-            raise
+        osutils.send_all(self._socket, bytes, self._report_activity)
 
     def _ensure_connection(self):
         """Connect this medium if not already connected."""

=== modified file 'bzrlib/tests/test_smart_transport.py'
--- a/bzrlib/tests/test_smart_transport.py	2011-11-25 17:54:52 +0000
+++ b/bzrlib/tests/test_smart_transport.py	2012-09-10 11:50:34 +0000
@@ -634,6 +634,24 @@
         self.assertRaises(
             errors.ConnectionError, client_medium._ensure_connection)
 
+    def test_disconnected_socket(self):
+        class DisconnectedSocket(object):
+            def __init__(self, err):
+                self.err = err
+            def send(self, content):
+                raise self.err
+            def close(self):
+                pass
+        # All of these should be treated as ConnectionReset
+        errs = []
+        for errnum in osutils._end_of_stream_errors:
+            errs.append(IOError(errnum))
+        for err in errs:
+            sock = DisconnectedSocket(err)
+            med = medium.SmartClientAlreadyConnectedSocketMedium('base', sock)
+            self.assertRaises(errors.ConnectionReset,
+                med.accept_bytes, 'some more content')
+
 
 class TestSmartClientStreamMediumRequest(tests.TestCase):
     """Tests the for SmartClientStreamMediumRequest.



More information about the bazaar-commits mailing list