mercurial/wireprotov2peer.py
author Gregory Szorc <gregory.szorc@gmail.com>
Sat, 14 Apr 2018 11:46:08 -0700
changeset 37720 d715a85003c8
parent 37719 a656cba08a04
child 37721 f7673845b167
permissions -rw-r--r--
wireprotov2: establish a type for representing command response It will be desirable to have a higher-level type for representing command responses. This will allow us to do nicer things. For now, the instance encapsulates existing logic. It is still a bit primitive. But we're slowly making things better. Version 1 protocols have a wrapping layer that decodes the raw string data into a data structure and that data structure is sent to the future. Version 2 doesn't yet have this layer and the future is receiving the raw wire response. Hence why debugcommands needed to be taught about the response type. Differential Revision: https://phab.mercurial-scm.org/D3380
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     1
# wireprotov2peer.py - client side code for wire protocol version 2
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     2
#
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     3
# Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     4
#
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     7
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     8
from __future__ import absolute_import
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     9
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    10
from .i18n import _
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    11
from .thirdparty import (
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    12
    cbor,
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    13
)
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    14
from . import (
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    15
    error,
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    16
    util,
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    17
    wireprotoframing,
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    18
)
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    19
37720
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    20
class commandresponse(object):
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    21
    """Represents the response to a command request."""
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    22
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    23
    def __init__(self, requestid, command):
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    24
        self.requestid = requestid
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    25
        self.command = command
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    26
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    27
        self.cbor = False
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    28
        self.b = util.bytesio()
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    29
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    30
    def cborobjects(self):
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    31
        """Obtain decoded CBOR objects from this response."""
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    32
        size = self.b.tell()
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    33
        self.b.seek(0)
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    34
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    35
        decoder = cbor.CBORDecoder(self.b)
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    36
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    37
        while self.b.tell() < size:
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    38
            yield decoder.decode()
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    39
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    40
class clienthandler(object):
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    41
    """Object to handle higher-level client activities.
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    42
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    43
    The ``clientreactor`` is used to hold low-level state about the frame-based
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    44
    protocol, such as which requests and streams are active. This type is used
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    45
    for higher-level operations, such as reading frames from a socket, exposing
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    46
    and managing a higher-level primitive for representing command responses,
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    47
    etc. This class is what peers should probably use to bridge wire activity
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    48
    with the higher-level peer API.
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    49
    """
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    50
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    51
    def __init__(self, ui, clientreactor):
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    52
        self._ui = ui
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    53
        self._reactor = clientreactor
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    54
        self._requests = {}
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    55
        self._futures = {}
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    56
        self._responses = {}
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    57
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    58
    def callcommand(self, command, args, f):
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    59
        """Register a request to call a command.
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    60
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    61
        Returns an iterable of frames that should be sent over the wire.
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    62
        """
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    63
        request, action, meta = self._reactor.callcommand(command, args)
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    64
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    65
        if action != 'noop':
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    66
            raise error.ProgrammingError('%s not yet supported' % action)
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    67
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    68
        rid = request.requestid
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    69
        self._requests[rid] = request
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    70
        self._futures[rid] = f
37720
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
    71
        self._responses[rid] = commandresponse(rid, command)
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    72
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    73
        return iter(())
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    74
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    75
    def flushcommands(self):
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    76
        """Flush all queued commands.
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    77
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    78
        Returns an iterable of frames that should be sent over the wire.
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    79
        """
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    80
        action, meta = self._reactor.flushcommands()
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    81
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    82
        if action != 'sendframes':
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    83
            raise error.ProgrammingError('%s not yet supported' % action)
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    84
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    85
        return meta['framegen']
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    86
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    87
    def readframe(self, fh):
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    88
        """Attempt to read and process a frame.
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    89
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    90
        Returns None if no frame was read. Presumably this means EOF.
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    91
        """
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    92
        frame = wireprotoframing.readframe(fh)
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    93
        if frame is None:
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    94
            # TODO tell reactor?
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    95
            return
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    96
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    97
        self._ui.note(_('received %r\n') % frame)
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    98
        self._processframe(frame)
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    99
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   100
        return True
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   101
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   102
    def _processframe(self, frame):
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   103
        """Process a single read frame."""
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   104
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   105
        action, meta = self._reactor.onframerecv(frame)
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   106
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   107
        if action == 'error':
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   108
            e = error.RepoError(meta['message'])
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   109
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   110
            if frame.requestid in self._futures:
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   111
                self._futures[frame.requestid].set_exception(e)
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   112
            else:
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   113
                raise e
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   114
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   115
        if frame.requestid not in self._requests:
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   116
            raise error.ProgrammingError(
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   117
                'received frame for unknown request; this is either a bug in '
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   118
                'the clientreactor not screening for this or this instance was '
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   119
                'never told about this request: %r' % frame)
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   120
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   121
        response = self._responses[frame.requestid]
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   122
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   123
        if action == 'responsedata':
37720
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
   124
            response.b.write(meta['data'])
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   125
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   126
            if meta['cbor']:
37720
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
   127
                response.cbor = True
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   128
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   129
            if meta['eos']:
37720
d715a85003c8 wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37719
diff changeset
   130
                self._futures[frame.requestid].set_result(response)
37719
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   131
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   132
                del self._requests[frame.requestid]
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   133
                del self._futures[frame.requestid]
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   134
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   135
        else:
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   136
            raise error.ProgrammingError(
a656cba08a04 wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   137
                'unhandled action from clientreactor: %s' % action)