[MERGE] Move protocol version querying logic into the medium
Andrew Bennetts
andrew at canonical.com
Wed Mar 26 10:04:28 GMT 2008
Robert Collins wrote:
> On Fri, 2008-02-29 at 20:07 +1100, Andrew Bennetts wrote:
> >
> > Thanks! I'll play around again with switching that to
> > get_smart_medium before I
> > merge.
>
> It should be trivial; they have the same method body :).
Actually, they have a subtly different method body, enough to make it not quite
trivial. One raises NoSmartServer, the other NoSmartMedium.
The attached merge directive implements this suggestion (and includes the
original changes). The issues that had to be dealt with were:
* errors.NoSmartMedium is not a subclass of NotBranchError, so the exception
handling in RemoteBzrDirFormat.probe_transport needed tweaking.
* HttpTransportBase get_smart_client always fails, but get_smart_medium
doesn't, which is probably a bug. So switching to get_smart_medium stops
masking this bug revealing a couple of issues:
* probing for a RemoteBzrDir on an HTTP transport where the HTTP host does
not allow POST requests (such as our test HTTP server) needed cleaner
handling in the HTTP smart client code. I also removed an assert while
I was there.
* there's a test in test_fetch that asserts that only 4 HTTP requests are
issued when opening a branch (well, it asserts that the server only logs
four lines, which is nearly the same thing). Probing for a smart
server, plus the error it causes the test HTTP server to log, bumped the
count to 6. So I made that part of that test re-use a transport that
had already done the probe, and made the medium cache a failed probe
just as it caches successful ones.
Also, this change means the only use of get_smart_client in bzrlib is now in
transport decorators and a single line test_remote. So we should probably
deprecate this method. Ditto for the errors.NoSmartServer exception. I'm happy
to do that deprecation as part of this change if you agree.
The new changes are extensive enough to be worth a second review, I think, so
here they are.
-Andrew.
-------------- next part --------------
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: andrew.bennetts at canonical.com-20080326095048-\
# 8eo3qp3w4rhamtt4
# target_branch: http://bazaar-vcs.org/bzr/bzr.dev
# testament_sha1: d9e92cdf3ac737b7b0eab48a0ddcd36011c17b98
# timestamp: 2008-03-26 20:51:07 +1100
# source_branch: http://people.ubuntu.com/~andrew/bzr/protocol-\
# versioning-logic-into-medium
# base_revision_id: pqm at pqm.ubuntu.com-20080326030652-vgwdkwda9mi8s200
#
# Begin patch
=== modified file 'bzrlib/bzrdir.py'
--- bzrlib/bzrdir.py 2008-03-12 01:06:03 +0000
+++ bzrlib/bzrdir.py 2008-03-26 09:50:48 +0000
@@ -2394,18 +2394,20 @@
def probe_transport(klass, transport):
"""Return a RemoteBzrDirFormat object if it looks possible."""
try:
- client = transport.get_smart_client()
+ medium = transport.get_smart_medium()
except (NotImplementedError, AttributeError,
- errors.TransportNotPossible):
+ errors.TransportNotPossible, errors.NoSmartMedium):
# no smart server, so not a branch for this format type.
raise errors.NotBranchError(path=transport.base)
else:
- # Send a 'hello' request in protocol version one, and decline to
- # open it if the server doesn't support our required version (2) so
- # that the VFS-based transport will do it.
- request = client.get_request()
- smart_protocol = protocol.SmartClientRequestProtocolOne(request)
- server_version = smart_protocol.query_version()
+ # Decline to open it if the server doesn't support our required
+ # version (2) so that the VFS-based transport will do it.
+ try:
+ server_version = medium.protocol_version()
+ except errors.SmartProtocolError:
+ # Apparently there's no usable smart server there, even though
+ # the medium supports the smart protocol.
+ raise errors.NotBranchError(path=transport.base)
if server_version != 2:
raise errors.NotBranchError(path=transport.base)
return klass()
=== modified file 'bzrlib/smart/medium.py'
--- bzrlib/smart/medium.py 2008-02-06 03:52:25 +0000
+++ bzrlib/smart/medium.py 2008-03-26 09:50:48 +0000
@@ -35,6 +35,7 @@
)
from bzrlib.smart.protocol import (
REQUEST_VERSION_TWO,
+ SmartClientRequestProtocolOne,
SmartServerRequestProtocolOne,
SmartServerRequestProtocolTwo,
)
@@ -368,6 +369,29 @@
class SmartClientMedium(object):
"""Smart client is a medium for sending smart protocol requests over."""
+ def __init__(self):
+ super(SmartClientMedium, self).__init__()
+ self._protocol_version_error = None
+ self._protocol_version = None
+
+ def protocol_version(self):
+ """Find out the best protocol version to use."""
+ if self._protocol_version_error is not None:
+ raise self._protocol_version_error
+ if self._protocol_version is None:
+ try:
+ medium_request = self.get_request()
+ # Send a 'hello' request in protocol version one, for maximum
+ # backwards compatibility.
+ client_protocol = SmartClientRequestProtocolOne(medium_request)
+ self._protocol_version = client_protocol.query_version()
+ except errors.SmartProtocolError, e:
+ # Cache the error, just like we would cache a successful
+ # result.
+ self._protocol_version_error = e
+ raise
+ return self._protocol_version
+
def disconnect(self):
"""If this medium maintains a persistent connection, close it.
@@ -385,6 +409,7 @@
"""
def __init__(self):
+ SmartClientMedium.__init__(self)
self._current_request = None
# Be optimistic: we assume the remote end can accept new remote
# requests until we get an error saying otherwise. (1.2 adds some
=== modified file 'bzrlib/tests/test_fetch.py'
--- bzrlib/tests/test_fetch.py 2007-12-11 14:26:18 +0000
+++ bzrlib/tests/test_fetch.py 2008-03-26 09:50:48 +0000
@@ -296,8 +296,12 @@
http_logs))
# FIXME naughty poking in there.
self.get_readonly_server().logs = []
- # check there is nothing more to fetch
- source = Branch.open(self.get_readonly_url("source/"))
+ # check there is nothing more to fetch. We take care to re-use the
+ # existing transport so that the request logs we're about to examine
+ # aren't cluttered with redundant probes for a smart server.
+ source = Branch.open(
+ self.get_readonly_url("source/"),
+ possible_transports=[source.bzrdir.root_transport])
self.assertEqual(target.fetch(source), (0, []))
# should make just two requests
http_logs = self.get_readonly_server().logs
=== modified file 'bzrlib/tests/test_remote.py'
--- bzrlib/tests/test_remote.py 2008-02-12 05:17:25 +0000
+++ bzrlib/tests/test_remote.py 2008-02-28 14:06:05 +0000
@@ -301,6 +301,9 @@
input_file, output_file)
return medium.SmartClientStreamMediumRequest(client_medium)
+ def protocol_version(self):
+ return 1
+
class OldServerTransport(object):
"""A fake transport for test_old_server that reports it's smart server
=== modified file 'bzrlib/transport/http/__init__.py'
--- bzrlib/transport/http/__init__.py 2008-01-02 14:13:55 +0000
+++ bzrlib/transport/http/__init__.py 2008-03-26 09:50:48 +0000
@@ -514,8 +514,14 @@
return ','.join(strings)
def send_http_smart_request(self, bytes):
- code, body_filelike = self._post(bytes)
- assert code == 200, 'unexpected HTTP response code %r' % (code,)
+ try:
+ code, body_filelike = self._post(bytes)
+ if code != 200:
+ raise InvalidHttpResponse(
+ self._remote_path('.bzr/smart'),
+ 'Expected 200 response code, got %r' % (code,))
+ except errors.InvalidHttpResponse, e:
+ raise errors.SmartProtocolError(str(e))
return body_filelike
# Begin bundle
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
OVC0pFZZlI5pgCEmZASf+LuSKcKEgQcBRDg=
More information about the bazaar
mailing list