~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/medium.py

  • Committer: Patch Queue Manager
  • Date: 2016-02-01 19:13:13 UTC
  • mfrom: (6614.2.2 trunk)
  • Revision ID: pqm@pqm.ubuntu.com-20160201191313-wdfvmfff1djde6oq
(vila) Release 2.7.0 (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
bzrlib/transport/smart/__init__.py.
25
25
"""
26
26
 
 
27
from __future__ import absolute_import
 
28
 
27
29
import errno
28
30
import os
29
31
import sys
30
32
import time
31
 
import urllib
32
33
 
33
34
import bzrlib
34
35
from bzrlib.lazy_import import lazy_import
42
43
    debug,
43
44
    errors,
44
45
    trace,
 
46
    transport,
45
47
    ui,
46
48
    urlutils,
47
49
    )
840
842
        """
841
843
        medium_base = urlutils.join(self.base, '/')
842
844
        rel_url = urlutils.relative_url(medium_base, transport.base)
843
 
        return urllib.unquote(rel_url)
 
845
        return urlutils.unquote(rel_url)
844
846
 
845
847
 
846
848
class SmartClientStreamMedium(SmartClientMedium):
881
883
        """
882
884
        return SmartClientStreamMediumRequest(self)
883
885
 
 
886
    def reset(self):
 
887
        """We have been disconnected, reset current state.
 
888
 
 
889
        This resets things like _current_request and connected state.
 
890
        """
 
891
        self.disconnect()
 
892
        self._current_request = None
 
893
 
884
894
 
885
895
class SmartSimplePipesClientMedium(SmartClientStreamMedium):
886
896
    """A client medium using simple pipes.
895
905
 
896
906
    def _accept_bytes(self, bytes):
897
907
        """See SmartClientStreamMedium.accept_bytes."""
898
 
        self._writeable_pipe.write(bytes)
 
908
        try:
 
909
            self._writeable_pipe.write(bytes)
 
910
        except IOError, e:
 
911
            if e.errno in (errno.EINVAL, errno.EPIPE):
 
912
                raise errors.ConnectionReset(
 
913
                    "Error trying to write to subprocess", e)
 
914
            raise
899
915
        self._report_activity(len(bytes), 'write')
900
916
 
901
917
    def _flush(self):
902
918
        """See SmartClientStreamMedium._flush()."""
 
919
        # Note: If flush were to fail, we'd like to raise ConnectionReset, etc.
 
920
        #       However, testing shows that even when the child process is
 
921
        #       gone, this doesn't error.
903
922
        self._writeable_pipe.flush()
904
923
 
905
924
    def _read_bytes(self, count):
924
943
 
925
944
class SmartSSHClientMedium(SmartClientStreamMedium):
926
945
    """A client medium using SSH.
927
 
    
928
 
    It delegates IO to a SmartClientSocketMedium or
 
946
 
 
947
    It delegates IO to a SmartSimplePipesClientMedium or
929
948
    SmartClientAlreadyConnectedSocketMedium (depending on platform).
930
949
    """
931
950
 
1003
1022
            raise AssertionError(
1004
1023
                "Unexpected io_kind %r from %r"
1005
1024
                % (io_kind, self._ssh_connection))
 
1025
        for hook in transport.Transport.hooks["post_connect"]:
 
1026
            hook(self)
1006
1027
 
1007
1028
    def _flush(self):
1008
1029
        """See SmartClientStreamMedium._flush()."""
1022
1043
 
1023
1044
class SmartClientSocketMedium(SmartClientStreamMedium):
1024
1045
    """A client medium using a socket.
1025
 
    
 
1046
 
1026
1047
    This class isn't usable directly.  Use one of its subclasses instead.
1027
1048
    """
1028
1049
 
1111
1132
            raise errors.ConnectionError("failed to connect to %s:%d: %s" %
1112
1133
                    (self._host, port, err_msg))
1113
1134
        self._connected = True
 
1135
        for hook in transport.Transport.hooks["post_connect"]:
 
1136
            hook(self)
1114
1137
 
1115
1138
 
1116
1139
class SmartClientAlreadyConnectedSocketMedium(SmartClientSocketMedium):
1168
1191
        This invokes self._medium._flush to ensure all bytes are transmitted.
1169
1192
        """
1170
1193
        self._medium._flush()
1171
 
 
1172