Rev 4905: Document the functions in the new class. in http://bazaar.launchpad.net/~jameinel/bzr/2.1-client-read-reconnect-819604
John Arbash Meinel
john at arbash-meinel.com
Sat Oct 8 10:23:45 UTC 2011
At http://bazaar.launchpad.net/~jameinel/bzr/2.1-client-read-reconnect-819604
------------------------------------------------------------
revno: 4905
revision-id: john at arbash-meinel.com-20111008102315-5y0yk3bnxhpa86el
parent: john at arbash-meinel.com-20111008094505-4s29efjowmf0abmi
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.1-client-read-reconnect-819604
timestamp: Sat 2011-10-08 12:23:15 +0200
message:
Document the functions in the new class.
-------------- next part --------------
=== modified file 'bzrlib/smart/client.py'
--- a/bzrlib/smart/client.py 2011-10-08 09:45:05 +0000
+++ b/bzrlib/smart/client.py 2011-10-08 10:23:15 +0000
@@ -16,7 +16,6 @@
import bzrlib
from bzrlib.smart import message, protocol
-from bzrlib.trace import warning
from bzrlib import (
errors,
hooks,
@@ -112,7 +111,17 @@
class _SmartClientRequest(object):
- """Encapsulate the logic for a single request."""
+ """Encapsulate the logic for a single request.
+
+ This class handles things like reconnecting and sending the request a
+ second time when the connection is reset in the middle. It also handles the
+ multiple requests that get made if we don't know what protocol the server
+ supports yet.
+
+ Generally, you build up one of these objects, passing in the arguments that
+ you want to send to the server, and then use 'call_and_read_response' to
+ get the response from the server.
+ """
def __init__(self, client, method, args, body=None, readv_body=None,
body_stream=None, expect_response_body=True):
@@ -125,11 +134,19 @@
self.expect_response_body = expect_response_body
def call_and_read_response(self):
+ """Send the request to the server, and read the initial response.
+
+ This doesn't read all of the body content of the response, instead it
+ returns (response_tuple, response_handler). response_tuple is the 'ok',
+ or 'error' information, and 'response_handler' can be used to get the
+ content stream out.
+ """
self._run_call_hooks()
- if self.client._medium._protocol_version is None:
+ protocol_version = self.client._medium._protocol_version
+ if protocol_version is None:
return self._call_determining_protocol_version()
else:
- return self._call()
+ return self._call(protocol_version)
def _run_call_hooks(self):
if not _SmartClient.hooks['call']:
@@ -139,27 +156,33 @@
for hook in _SmartClient.hooks['call']:
hook(params)
+ def _call(self, protocol_version):
+ """We know the protocol version.
- def _call(self):
- response_handler = self._send(
- self.client._medium._protocol_version)
+ So this just sends the request, and then reads the response. This is
+ 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)
return (response_tuple, response_handler)
def _call_determining_protocol_version(self):
+ """Determine what protocol the remote server supports.
+
+ We do this by placing a request in the most recent protocol, and
+ handling the UnexpectedProtocolVersionMarker from the server.
+ """
for protocol_version in [3, 2]:
if protocol_version == 2:
# If v3 doesn't work, the remote side is older than 1.6.
self.client._medium._remember_remote_is_before((1, 6))
- response_handler = self._send(protocol_version)
try:
- response_tuple = response_handler.read_response_tuple(
- expect_body=self.expect_response_body)
+ response_tuple, response_handler = self._call(protocol_version)
except errors.UnexpectedProtocolVersionMarker, err:
# TODO: We could recover from this without disconnecting if
# we recognise the protocol version.
- warning(
+ trace.warning(
'Server does not understand Bazaar network protocol %d,'
' reconnecting. (Upgrade the server to avoid this.)'
% (protocol_version,))
@@ -177,6 +200,7 @@
'Server is not a Bazaar server: ' + str(err))
def _construct_protocol(self, version):
+ """Build the encoding stack for a given protocol version."""
request = self.client._medium.get_request()
if version == 3:
request_encoder = protocol.ProtocolThreeRequester(request)
@@ -193,6 +217,14 @@
return request_encoder, response_handler
def _send(self, protocol_version):
+ """Encode the request, and send it to the server.
+
+ This will retry a request if we get a ConnectionReset while sending the
+ request to the server. (Unless we have a body_stream that we have
+ already started consuming, since we can't restart body_streams)
+
+ :return: response_handler as defined by _construct_protocol
+ """
encoder, response_handler = self._construct_protocol(protocol_version)
try:
self._send_no_retry(encoder)
@@ -206,9 +238,8 @@
# Connection is dead, so close our end of it.
self.client._medium.reset()
if self.body_stream is not None:
- # We can't determine how much of body_stream got consumed
- # before we noticed the connection is down, so we don't retry
- # here.
+ # We can't restart a body_stream that has been partially
+ # consumed, so we don't retry.
raise
trace.log_exception_quietly()
trace.warning('ConnectionReset calling %s, retrying'
@@ -219,6 +250,7 @@
return response_handler
def _send_no_retry(self, encoder):
+ """Just encode the request and try to send it."""
encoder.set_headers(self.client._headers)
if self.body is not None:
if self.readv_body is not None:
More information about the bazaar-commits
mailing list