~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-02-06 16:38:04 UTC
  • mfrom: (3207.1.2 jam-integration)
  • Revision ID: pqm@pqm.ubuntu.com-20080206163804-6zyjbbfpsm8txfdm
(Lukas) give a better error when using version-info --custom without
        --template

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
    zero_ninetyone,
43
43
    )
44
44
from bzrlib.revision import NULL_REVISION
45
 
from bzrlib.trace import mutter, note, warning
 
45
from bzrlib.trace import mutter, note
46
46
 
47
47
# Note: RemoteBzrDirFormat is in bzrdir.py
48
48
 
777
777
        """See bzrlib.Graph.get_parent_map()."""
778
778
        # Hack to build up the caching logic.
779
779
        ancestry = self._parents_map
780
 
        if ancestry is None:
781
 
            # Repository is not locked, so there's no cache.
782
 
            missing_revisions = set(keys)
783
 
            ancestry = {}
784
 
        else:
785
 
            missing_revisions = set(key for key in keys if key not in ancestry)
 
780
        missing_revisions = set(key for key in keys if key not in ancestry)
786
781
        if missing_revisions:
787
782
            parent_map = self._get_parent_map(missing_revisions)
788
783
            if 'hpss' in debug.debug_flags:
789
784
                mutter('retransmitted revisions: %d of %d',
790
 
                        len(set(ancestry).intersection(parent_map)),
 
785
                        len(set(self._parents_map).intersection(parent_map)),
791
786
                        len(parent_map))
792
 
            ancestry.update(parent_map)
 
787
            self._parents_map.update(parent_map)
793
788
        present_keys = [k for k in keys if k in ancestry]
794
789
        if 'hpss' in debug.debug_flags:
795
790
            self._requested_parents.update(present_keys)
796
791
            mutter('Current RemoteRepository graph hit rate: %d%%',
797
 
                100.0 * len(self._requested_parents) / len(ancestry))
 
792
                100.0 * len(self._requested_parents) / len(self._parents_map))
798
793
        return dict((k, ancestry[k]) for k in present_keys)
799
794
 
800
795
    def _response_is_unknown_method(self, response, verb):
817
812
 
818
813
    def _get_parent_map(self, keys):
819
814
        """Helper for get_parent_map that performs the RPC."""
820
 
        medium = self._client.get_smart_medium()
821
 
        if not medium._remote_is_at_least_1_2:
822
 
            # We already found out that the server can't understand
823
 
            # Repository.get_parent_map requests, so just fetch the whole
824
 
            # graph.
825
 
            return self.get_revision_graph()
826
 
 
827
815
        keys = set(keys)
828
816
        if NULL_REVISION in keys:
829
817
            keys.discard(NULL_REVISION)
843
831
        # TODO: Manage this incrementally to avoid covering the same path
844
832
        # repeatedly. (The server will have to on each request, but the less
845
833
        # work done the better).
846
 
        parents_map = self._parents_map
847
 
        if parents_map is None:
848
 
            # Repository is not locked, so there's no cache.
849
 
            parents_map = {}
850
 
        start_set = set(parents_map)
 
834
        start_set = set(self._parents_map)
851
835
        result_parents = set()
852
 
        for parents in parents_map.itervalues():
 
836
        for parents in self._parents_map.itervalues():
853
837
            result_parents.update(parents)
854
838
        stop_keys = result_parents.difference(start_set)
855
839
        included_keys = start_set.intersection(result_parents)
856
840
        start_set.difference_update(included_keys)
857
 
        recipe = (start_set, stop_keys, len(parents_map))
 
841
        recipe = (start_set, stop_keys, len(self._parents_map))
858
842
        body = self._serialise_search_recipe(recipe)
859
843
        path = self.bzrdir._path_for_remote_call(self._client)
860
844
        for key in keys:
864
848
        response = self._client.call_with_body_bytes_expecting_body(
865
849
            verb, args, self._serialise_search_recipe(recipe))
866
850
        if self._response_is_unknown_method(response, verb):
867
 
            # Server does not support this method, so get the whole graph.
868
 
            # Worse, we have to force a disconnection, because the server now
869
 
            # doesn't realise it has a body on the wire to consume, so the
870
 
            # only way to recover is to abandon the connection.
871
 
            warning(
872
 
                'Server is too old for fast get_parent_map, reconnecting.  '
873
 
                '(Upgrade the server to Bazaar 1.2 to avoid this)')
874
 
            medium.disconnect()
875
 
            # To avoid having to disconnect repeatedly, we keep track of the
876
 
            # fact the server doesn't understand remote methods added in 1.2.
877
 
            medium._remote_is_at_least_1_2 = False
878
 
            return self.get_revision_graph()
 
851
            # Server that does not support this method, get the whole graph.
 
852
            response = self._client.call_expecting_body(
 
853
                'Repository.get_revision_graph', path, '')
 
854
            if response[0][0] not in ['ok', 'nosuchrevision']:
 
855
                reponse[1].cancel_read_body()
 
856
                raise errors.UnexpectedSmartServerResponse(response[0])
879
857
        elif response[0][0] not in ['ok']:
880
858
            reponse[1].cancel_read_body()
881
859
            raise errors.UnexpectedSmartServerResponse(response[0])
1031
1009
        return self._real_repository.has_signature_for_revision_id(revision_id)
1032
1010
 
1033
1011
    def get_data_stream_for_search(self, search):
1034
 
        medium = self._client.get_smart_medium()
1035
 
        if not medium._remote_is_at_least_1_2:
1036
 
            self._ensure_real()
1037
 
            return self._real_repository.get_data_stream_for_search(search)
1038
1012
        REQUEST_NAME = 'Repository.stream_revisions_chunked'
1039
1013
        path = self.bzrdir._path_for_remote_call(self._client)
1040
1014
        body = self._serialise_search_recipe(search.get_recipe())
1041
1015
        response, protocol = self._client.call_with_body_bytes_expecting_body(
1042
1016
            REQUEST_NAME, (path,), body)
1043
1017
 
1044
 
        if self._response_is_unknown_method((response, protocol), REQUEST_NAME):
1045
 
            # Server does not support this method, so fall back to VFS.
1046
 
            # Worse, we have to force a disconnection, because the server now
1047
 
            # doesn't realise it has a body on the wire to consume, so the
1048
 
            # only way to recover is to abandon the connection.
1049
 
            warning(
1050
 
                'Server is too old for streaming pull, reconnecting.  '
1051
 
                '(Upgrade the server to Bazaar 1.2 to avoid this)')
1052
 
            medium.disconnect()
1053
 
            # To avoid having to disconnect repeatedly, we keep track of the
1054
 
            # fact the server doesn't understand this remote method.
1055
 
            medium._remote_is_at_least_1_2 = False
1056
 
            self._ensure_real()
1057
 
            return self._real_repository.get_data_stream_for_search(search)
1058
 
 
1059
1018
        if response == ('ok',):
1060
1019
            return self._deserialise_stream(protocol)
1061
1020
        if response == ('NoSuchRevision', ):
1062
1021
            # We cannot easily identify the revision that is missing in this
1063
1022
            # situation without doing much more network IO. For now, bail.
1064
1023
            raise NoSuchRevision(self, "unknown")
 
1024
        elif (response == ('error', "Generic bzr smart protocol error: "
 
1025
                "bad request '%s'" % REQUEST_NAME) or
 
1026
              response == ('error', "Generic bzr smart protocol error: "
 
1027
                "bad request u'%s'" % REQUEST_NAME)):
 
1028
            protocol.cancel_read_body()
 
1029
            self._ensure_real()
 
1030
            return self._real_repository.get_data_stream_for_search(search)
1065
1031
        else:
1066
1032
            raise errors.UnexpectedSmartServerResponse(response)
1067
1033