Rev 4909: Start implementing retry during read. in http://bazaar.launchpad.net/~jameinel/bzr/2.1-client-read-reconnect-819604

John Arbash Meinel john at arbash-meinel.com
Mon Oct 10 12:32:03 UTC 2011


At http://bazaar.launchpad.net/~jameinel/bzr/2.1-client-read-reconnect-819604

------------------------------------------------------------
revno: 4909
revision-id: john at arbash-meinel.com-20111010123145-eflrykyvowqkdq2y
parent: john at arbash-meinel.com-20111010121329-uhx7q6ppna5cd1gn
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.1-client-read-reconnect-819604
timestamp: Mon 2011-10-10 14:31:45 +0200
message:
  Start implementing retry during read.
-------------- next part --------------
=== modified file 'bzrlib/smart/client.py'
--- a/bzrlib/smart/client.py	2011-10-08 10:23:15 +0000
+++ b/bzrlib/smart/client.py	2011-10-10 12:31:45 +0000
@@ -163,8 +163,17 @@
         where the code will be to retry requests if the connection is closed.
         """
         response_handler = self._send(protocol_version)
-        response_tuple = response_handler.read_response_tuple(
-            expect_body=self.expect_response_body)
+        try:
+            response_tuple = response_handler.read_response_tuple(
+                expect_body=self.expect_response_body)
+        except errors.ConnectionReset, e:
+            self.client._medium.reset()
+            trace.warning('ConnectionReset reading response for %r, retrying'
+                          % (self.method,))
+            trace.log_exception_quietly()
+            response_handler = self._send(protocol_version)
+            response_tuple = response_handler.read_response_tuple(
+                expect_body=self.expect_response_body)
         return (response_tuple, response_handler)
 
     def _call_determining_protocol_version(self):

=== modified file 'bzrlib/tests/test_smart_transport.py'
--- a/bzrlib/tests/test_smart_transport.py	2011-10-10 12:06:48 +0000
+++ b/bzrlib/tests/test_smart_transport.py	2011-10-10 12:31:45 +0000
@@ -3381,10 +3381,10 @@
 
 class Test_SmartClientRequest(tests.TestCase):
 
-    def make_client_with_failing_medium(self, fail_at_write=True):
-        response = StringIO()
+    def make_client_with_failing_medium(self, fail_at_write=True, response=''):
+        response_io = StringIO(response)
         output = StringIO()
-        vendor = FirstRejectedStringIOSSHVendor(response, output,
+        vendor = FirstRejectedStringIOSSHVendor(response_io, output,
                     fail_at_write=fail_at_write)
         client_medium = medium.SmartSSHClientMedium(
             'a host', 'a port', 'a user', 'a pass', 'base', vendor,
@@ -3392,6 +3392,32 @@
         smart_client = client._SmartClient(client_medium, headers={})
         return output, vendor, smart_client
 
+    def make_response(self, args, body=None, body_stream=None):
+        response_io = StringIO()
+        response = _mod_request.SuccessfulSmartServerResponse(args, body=body,
+            body_stream=body_stream)
+        responder = protocol.ProtocolThreeResponder(response_io.write)
+        responder.send_response(response)
+        return response_io.getvalue()
+
+    def test__call_doesnt_retry_append(self):
+        response = self.make_response(('appended', '8'))
+        output, vendor, smart_client = self.make_client_with_failing_medium(
+            fail_at_write=False, response=response)
+        smart_request = client._SmartClientRequest(smart_client, 'append',
+            ('foo', ''), body='content\n')
+        self.assertRaises(errors.ConnectionReset, smart_request._call, 3)
+
+    def test__call_retries_get_bytes(self):
+        response = self.make_response(('ok',), 'content\n')
+        output, vendor, smart_client = self.make_client_with_failing_medium(
+            fail_at_write=False, response=response)
+        smart_request = client._SmartClientRequest(smart_client, 'get',
+            ('foo',))
+        response, response_handler = smart_request._call(3)
+        self.assertEqual(('ok',), response)
+        self.assertEqual('content\n', response_handler.read_body_bytes())
+
     def test__send_no_retry_pipes(self):
         client_read, server_write = create_file_pipes()
         server_read, client_write = create_file_pipes()



More information about the bazaar-commits mailing list