Rev 4910: Do a lookup in 'request.request_handlers', to figure out if a request can be retried. 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:40:15 UTC 2011


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

------------------------------------------------------------
revno: 4910
revision-id: john at arbash-meinel.com-20111010123957-mdt3zijmjakh0vtd
parent: john at arbash-meinel.com-20111010123145-eflrykyvowqkdq2y
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.1-client-read-reconnect-819604
timestamp: Mon 2011-10-10 14:39:57 +0200
message:
  Do a lookup in 'request.request_handlers', to figure out if a request can be retried.
-------------- next part --------------
=== modified file 'bzrlib/smart/client.py'
--- a/bzrlib/smart/client.py	2011-10-10 12:31:45 +0000
+++ b/bzrlib/smart/client.py	2011-10-10 12:39:57 +0000
@@ -14,6 +14,11 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
+from bzrlib import lazy_import
+lazy_import.lazy_import(globals(), """
+from bzrlib.smart import request as _mod_request
+""")
+
 import bzrlib
 from bzrlib.smart import message, protocol
 from bzrlib import (
@@ -148,6 +153,22 @@
         else:
             return self._call(protocol_version)
 
+    def _is_safe_to_send_twice(self):
+        """Check if the current method is re-entrant safe."""
+        if self.body_stream is not None:
+            # We can't restart a body stream that has already been consumed.
+            return False
+        request_type = _mod_request.request_handlers.get_info(self.method)
+        if request_type in ('read', 'idem', 'semi'):
+            return True
+        # If we have gotten this far, 'stream' cannot be retried, because we
+        # already consumed the local stream.
+        if request_type in ('semivfs', 'mutate', 'stream'):
+            return False
+        trace.mutter('Unknown request type: %s for method %s'
+                     % (request_type, self.method))
+        return False
+
     def _run_call_hooks(self):
         if not _SmartClient.hooks['call']:
             return
@@ -168,6 +189,8 @@
                 expect_body=self.expect_response_body)
         except errors.ConnectionReset, e:
             self.client._medium.reset()
+            if not self._is_safe_to_send_twice():
+                raise
             trace.warning('ConnectionReset reading response for %r, retrying'
                           % (self.method,))
             trace.log_exception_quietly()



More information about the bazaar-commits mailing list