mercurial/wireprotov1peer.py
author Yuya Nishihara <yuya@tcha.org>
Mon, 12 Nov 2018 21:28:54 +0900
changeset 40595 419d703115b0
parent 39588 f15a587d2dfc
child 41055 55e8da487b8a
permissions -rw-r--r--
help: add internals.extensions topic I think it's better to include the API overview in core as we now have the internals section in our help system. Retrieved from the wiki, and formatted as reST. Several wiki links are removed since they are invalid in the help. The sections about example extension are removed at all as they seemed too verbose. https://www.mercurial-scm.org/wiki/WritingExtensions
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37614
a81d02ea65db wireproto: move version 1 peer functionality to standalone module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37613
diff changeset
     1
# wireprotov1peer.py - Client-side functionality for wire protocol version 1.
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2005-2010 Matt Mackall <mpm@selenic.com>
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
     8
from __future__ import absolute_import
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
     9
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29216
diff changeset
    10
import hashlib
37630
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
    11
import sys
37631
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
    12
import weakref
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    14
from .i18n import _
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    15
from .node import (
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    16
    bin,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    17
)
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    18
from . import (
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    19
    bundle2,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    20
    changegroup as changegroupmod,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    21
    encoding,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    22
    error,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    23
    pushkey as pushkeymod,
30924
48dea083f66d py3: convert the mode argument of os.fdopen to unicodes (1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30914
diff changeset
    24
    pycompat,
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
    25
    repository,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    26
    util,
36073
cd6ab329c5c7 wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36071
diff changeset
    27
    wireprototypes,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    28
)
37810
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37669
diff changeset
    29
from .utils import (
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37669
diff changeset
    30
    interfaceutil,
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37669
diff changeset
    31
)
20903
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    32
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
    33
urlreq = util.urlreq
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
    34
37615
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    35
def batchable(f):
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    36
    '''annotation for batchable methods
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    37
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    38
    Such methods must implement a coroutine as follows:
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    39
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    40
    @batchable
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    41
    def sample(self, one, two=None):
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    42
        # Build list of encoded arguments suitable for your wire protocol:
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    43
        encargs = [('one', encode(one),), ('two', encode(two),)]
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    44
        # Create future for injection of encoded result:
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    45
        encresref = future()
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    46
        # Return encoded arguments and future:
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    47
        yield encargs, encresref
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    48
        # Assuming the future to be filled with the result from the batched
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    49
        # request now. Decode it:
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    50
        yield decode(encresref.value)
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    51
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    52
    The decorator returns a function which wraps this coroutine as a plain
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    53
    method, but adds the original method as an attribute called "batchable",
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    54
    which is used by remotebatch to split the call into separate encoding and
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    55
    decoding phases.
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    56
    '''
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    57
    def plain(*args, **opts):
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    58
        batchable = f(*args, **opts)
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    59
        encargsorres, encresref = next(batchable)
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    60
        if not encresref:
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    61
            return encargsorres # a local result in this case
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    62
        self = args[0]
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    63
        cmd = pycompat.bytesurl(f.__name__)  # ensure cmd is ascii bytestr
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    64
        encresref.set(self._submitone(cmd, encargsorres))
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    65
        return next(batchable)
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    66
    setattr(plain, 'batchable', f)
39588
f15a587d2dfc wireprotov1peer: forward __name__ of wrapped method in batchable decorator
Augie Fackler <raf@durin42.com>
parents: 38783
diff changeset
    67
    setattr(plain, '__name__', f.__name__)
37615
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    68
    return plain
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    69
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    70
class future(object):
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    71
    '''placeholder for a value to be set later'''
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    72
    def set(self, value):
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    73
        if util.safehasattr(self, 'value'):
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    74
            raise error.RepoError("future is already set")
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    75
        self.value = value
f3dc8239e3a9 peer: scatter module to the wind (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
    76
29733
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
    77
def encodebatchcmds(req):
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
    78
    """Return a ``cmds`` argument value for the ``batch`` command."""
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
    79
    escapearg = wireprototypes.escapebatcharg
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
    80
29733
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
    81
    cmds = []
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
    82
    for op, argsdict in req:
29734
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
    83
        # Old servers didn't properly unescape argument names. So prevent
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
    84
        # the sending of argument names that may not be decoded properly by
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
    85
        # servers.
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
    86
        assert all(escapearg(k) == k for k in argsdict)
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
    87
29733
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
    88
        args = ','.join('%s=%s' % (escapearg(k), escapearg(v))
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
    89
                        for k, v in argsdict.iteritems())
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
    90
        cmds.append('%s %s' % (op, args))
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
    91
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
    92
    return ';'.join(cmds)
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
    93
37631
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
    94
class unsentfuture(pycompat.futures.Future):
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
    95
    """A Future variation to represent an unsent command.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
    96
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
    97
    Because we buffer commands and don't submit them immediately, calling
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
    98
    ``result()`` on an unsent future could deadlock. Futures for buffered
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
    99
    commands are represented by this type, which wraps ``result()`` to
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   100
    call ``sendcommands()``.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   101
    """
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   102
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   103
    def result(self, timeout=None):
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   104
        if self.done():
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   105
            return pycompat.futures.Future.result(self, timeout)
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   106
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   107
        self._peerexecutor.sendcommands()
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   108
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   109
        # This looks like it will infinitely recurse. However,
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   110
        # sendcommands() should modify __class__. This call serves as a check
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   111
        # on that.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   112
        return self.result(timeout)
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   113
37810
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37669
diff changeset
   114
@interfaceutil.implementer(repository.ipeercommandexecutor)
37630
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   115
class peerexecutor(object):
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   116
    def __init__(self, peer):
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   117
        self._peer = peer
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   118
        self._sent = False
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   119
        self._closed = False
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   120
        self._calls = []
37631
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   121
        self._futures = weakref.WeakSet()
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   122
        self._responseexecutor = None
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   123
        self._responsef = None
37630
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   124
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   125
    def __enter__(self):
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   126
        return self
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   127
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   128
    def __exit__(self, exctype, excvalee, exctb):
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   129
        self.close()
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   130
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   131
    def callcommand(self, command, args):
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   132
        if self._sent:
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   133
            raise error.ProgrammingError('callcommand() cannot be used '
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   134
                                         'after commands are sent')
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   135
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   136
        if self._closed:
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   137
            raise error.ProgrammingError('callcommand() cannot be used '
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   138
                                         'after close()')
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   139
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   140
        # Commands are dispatched through methods on the peer.
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   141
        fn = getattr(self._peer, pycompat.sysstr(command), None)
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   142
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   143
        if not fn:
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   144
            raise error.ProgrammingError(
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   145
                'cannot call command %s: method of same name not available '
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   146
                'on peer' % command)
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   147
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   148
        # Commands are either batchable or they aren't. If a command
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   149
        # isn't batchable, we send it immediately because the executor
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   150
        # can no longer accept new commands after a non-batchable command.
37631
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   151
        # If a command is batchable, we queue it for later. But we have
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   152
        # to account for the case of a non-batchable command arriving after
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   153
        # a batchable one and refuse to service it.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   154
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   155
        def addcall():
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   156
            f = pycompat.futures.Future()
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   157
            self._futures.add(f)
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   158
            self._calls.append((command, args, fn, f))
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   159
            return f
37630
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   160
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   161
        if getattr(fn, 'batchable', False):
37631
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   162
            f = addcall()
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   163
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   164
            # But since we don't issue it immediately, we wrap its result()
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   165
            # to trigger sending so we avoid deadlocks.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   166
            f.__class__ = unsentfuture
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   167
            f._peerexecutor = self
37630
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   168
        else:
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   169
            if self._calls:
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   170
                raise error.ProgrammingError(
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   171
                    '%s is not batchable and cannot be called on a command '
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   172
                    'executor along with other commands' % command)
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   173
37631
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   174
            f = addcall()
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   175
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   176
            # Non-batchable commands can never coexist with another command
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   177
            # in this executor. So send the command immediately.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   178
            self.sendcommands()
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   179
37630
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   180
        return f
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   181
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   182
    def sendcommands(self):
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   183
        if self._sent:
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   184
            return
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   185
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   186
        if not self._calls:
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   187
            return
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   188
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   189
        self._sent = True
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   190
37631
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   191
        # Unhack any future types so caller seens a clean type and to break
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   192
        # cycle between us and futures.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   193
        for f in self._futures:
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   194
            if isinstance(f, unsentfuture):
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   195
                f.__class__ = pycompat.futures.Future
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   196
                f._peerexecutor = None
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   197
37630
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   198
        calls = self._calls
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   199
        # Mainly to destroy references to futures.
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   200
        self._calls = None
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   201
37631
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   202
        # Simple case of a single command. We call it synchronously.
37630
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   203
        if len(calls) == 1:
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   204
            command, args, fn, f = calls[0]
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   205
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   206
            # Future was cancelled. Ignore it.
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   207
            if not f.set_running_or_notify_cancel():
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   208
                return
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   209
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   210
            try:
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   211
                result = fn(**pycompat.strkwargs(args))
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   212
            except Exception:
37669
1cb54e6193a6 py3: paper over differences in future exception handling
Augie Fackler <augie@google.com>
parents: 37650
diff changeset
   213
                pycompat.future_set_exception_info(f, sys.exc_info()[1:])
37630
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   214
            else:
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   215
                f.set_result(result)
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   216
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   217
            return
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   218
37631
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   219
        # Batch commands are a bit harder. First, we have to deal with the
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   220
        # @batchable coroutine. That's a bit annoying. Furthermore, we also
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   221
        # need to preserve streaming. i.e. it should be possible for the
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   222
        # futures to resolve as data is coming in off the wire without having
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   223
        # to wait for the final byte of the final response. We do this by
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   224
        # spinning up a thread to read the responses.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   225
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   226
        requests = []
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   227
        states = []
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   228
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   229
        for command, args, fn, f in calls:
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   230
            # Future was cancelled. Ignore it.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   231
            if not f.set_running_or_notify_cancel():
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   232
                continue
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   233
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   234
            try:
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   235
                batchable = fn.batchable(fn.__self__,
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   236
                                         **pycompat.strkwargs(args))
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   237
            except Exception:
37669
1cb54e6193a6 py3: paper over differences in future exception handling
Augie Fackler <augie@google.com>
parents: 37650
diff changeset
   238
                pycompat.future_set_exception_info(f, sys.exc_info()[1:])
37631
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   239
                return
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   240
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   241
            # Encoded arguments and future holding remote result.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   242
            try:
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   243
                encodedargs, fremote = next(batchable)
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   244
            except Exception:
37669
1cb54e6193a6 py3: paper over differences in future exception handling
Augie Fackler <augie@google.com>
parents: 37650
diff changeset
   245
                pycompat.future_set_exception_info(f, sys.exc_info()[1:])
37631
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   246
                return
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   247
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   248
            requests.append((command, encodedargs))
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   249
            states.append((command, f, batchable, fremote))
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   250
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   251
        if not requests:
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   252
            return
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   253
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   254
        # This will emit responses in order they were executed.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   255
        wireresults = self._peer._submitbatch(requests)
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   256
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   257
        # The use of a thread pool executor here is a bit weird for something
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   258
        # that only spins up a single thread. However, thread management is
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   259
        # hard and it is easy to encounter race conditions, deadlocks, etc.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   260
        # concurrent.futures already solves these problems and its thread pool
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   261
        # executor has minimal overhead. So we use it.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   262
        self._responseexecutor = pycompat.futures.ThreadPoolExecutor(1)
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   263
        self._responsef = self._responseexecutor.submit(self._readbatchresponse,
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   264
                                                        states, wireresults)
37630
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   265
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   266
    def close(self):
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   267
        self.sendcommands()
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   268
37631
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   269
        if self._closed:
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   270
            return
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   271
37630
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   272
        self._closed = True
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   273
37631
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   274
        if not self._responsef:
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   275
            return
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   276
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   277
        # We need to wait on our in-flight response and then shut down the
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   278
        # executor once we have a result.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   279
        try:
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   280
            self._responsef.result()
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   281
        finally:
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   282
            self._responseexecutor.shutdown(wait=True)
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   283
            self._responsef = None
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   284
            self._responseexecutor = None
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   285
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   286
            # If any of our futures are still in progress, mark them as
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   287
            # errored. Otherwise a result() could wait indefinitely.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   288
            for f in self._futures:
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   289
                if not f.done():
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   290
                    f.set_exception(error.ResponseError(
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   291
                        _('unfulfilled batch command response')))
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   292
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   293
            self._futures = None
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   294
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   295
    def _readbatchresponse(self, states, wireresults):
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   296
        # Executes in a thread to read data off the wire.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   297
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   298
        for command, f, batchable, fremote in states:
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   299
            # Grab raw result off the wire and teach the internal future
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   300
            # about it.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   301
            remoteresult = next(wireresults)
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   302
            fremote.set(remoteresult)
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   303
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   304
            # And ask the coroutine to decode that value.
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   305
            try:
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   306
                result = next(batchable)
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   307
            except Exception:
37669
1cb54e6193a6 py3: paper over differences in future exception handling
Augie Fackler <augie@google.com>
parents: 37650
diff changeset
   308
                pycompat.future_set_exception_info(f, sys.exc_info()[1:])
37631
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   309
            else:
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   310
                f.set_result(result)
2f626233859b wireproto: implement batching on peer executor interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37630
diff changeset
   311
37810
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37669
diff changeset
   312
@interfaceutil.implementer(repository.ipeercommands,
856f381ad74b interfaceutil: module to stub out zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37669
diff changeset
   313
                           repository.ipeerlegacycommands)
37635
cc8c06835097 wireproto: convert legacy commands to command executor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37633
diff changeset
   314
class wirepeer(repository.peer):
27243
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   315
    """Client-side interface for communicating with a peer repository.
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   316
27243
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   317
    Methods commonly call wire protocol commands of the same name.
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   318
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   319
    See also httppeer.py and sshpeer.py for protocol-specific
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   320
    implementations of this interface.
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   321
    """
37630
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   322
    def commandexecutor(self):
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   323
        return peerexecutor(self)
e1b32dc4646c wireproto: implement command executor interface for version 1 peers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37615
diff changeset
   324
37320
39f7d4ee8bcd repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37295
diff changeset
   325
    # Begin of ipeercommands interface.
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   326
37649
a168799687e5 wireproto: properly call clonebundles command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37646
diff changeset
   327
    def clonebundles(self):
a168799687e5 wireproto: properly call clonebundles command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37646
diff changeset
   328
        self.requirecap('clonebundles', _('clone bundles'))
a168799687e5 wireproto: properly call clonebundles command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37646
diff changeset
   329
        return self._call('clonebundles')
a168799687e5 wireproto: properly call clonebundles command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37646
diff changeset
   330
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   331
    @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   332
    def lookup(self, key):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   333
        self.requirecap('lookup', _('look up remote revision'))
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   334
        f = future()
20671
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   335
        yield {'key': encoding.fromlocal(key)}, f
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   336
        d = f.value
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   337
        success, data = d[:-1].split(" ", 1)
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   338
        if int(success):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   339
            yield bin(data)
34062
6c6169f71b8d wireproto: do not abort after successful lookup
Kyle Lippincott <spectral@google.com>
parents: 33806
diff changeset
   340
        else:
6c6169f71b8d wireproto: do not abort after successful lookup
Kyle Lippincott <spectral@google.com>
parents: 33806
diff changeset
   341
            self._abort(error.RepoError(data))
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   342
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   343
    @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   344
    def heads(self):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   345
        f = future()
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   346
        yield {}, f
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   347
        d = f.value
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   348
        try:
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   349
            yield wireprototypes.decodelist(d[:-1])
13726
378522bdc059 wireproto: avoid naked excepts
Matt Mackall <mpm@selenic.com>
parents: 13723
diff changeset
   350
        except ValueError:
11879
4e804302d30c fix undefined variables, spotted by pylint
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11627
diff changeset
   351
            self._abort(error.ResponseError(_("unexpected response:"), d))
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   352
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   353
    @batchable
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   354
    def known(self, nodes):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   355
        f = future()
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   356
        yield {'nodes': wireprototypes.encodelist(nodes)}, f
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   357
        d = f.value
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   358
        try:
38328
aa9dd805234d py3: fix loop over byte string in wireprotov1peer
Yuya Nishihara <yuya@tcha.org>
parents: 37810
diff changeset
   359
            yield [bool(int(b)) for b in pycompat.iterbytestr(d)]
13726
378522bdc059 wireproto: avoid naked excepts
Matt Mackall <mpm@selenic.com>
parents: 13723
diff changeset
   360
        except ValueError:
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   361
            self._abort(error.ResponseError(_("unexpected response:"), d))
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   362
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   363
    @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   364
    def branchmap(self):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   365
        f = future()
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   366
        yield {}, f
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   367
        d = f.value
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   368
        try:
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   369
            branchmap = {}
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   370
            for branchpart in d.splitlines():
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   371
                branchname, branchheads = branchpart.split(' ', 1)
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
   372
                branchname = encoding.tolocal(urlreq.unquote(branchname))
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   373
                branchheads = wireprototypes.decodelist(branchheads)
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   374
                branchmap[branchname] = branchheads
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   375
            yield branchmap
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   376
        except TypeError:
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   377
            self._abort(error.ResponseError(_("unexpected response:"), d))
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   378
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   379
    @batchable
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   380
    def listkeys(self, namespace):
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   381
        if not self.capable('pushkey'):
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   382
            yield {}, None
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   383
        f = future()
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   384
        self.ui.debug('preparing listkeys for "%s"\n' % namespace)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   385
        yield {'namespace': encoding.fromlocal(namespace)}, f
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   386
        d = f.value
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   387
        self.ui.debug('received listkey for "%s": %i bytes\n'
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   388
                      % (namespace, len(d)))
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   389
        yield pushkeymod.decodekeys(d)
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   390
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   391
    @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   392
    def pushkey(self, namespace, key, old, new):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   393
        if not self.capable('pushkey'):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   394
            yield False, None
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   395
        f = future()
17293
d3f84ccc5495 pushkey: add more verbose debug output regarding pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17205
diff changeset
   396
        self.ui.debug('preparing pushkey for "%s:%s"\n' % (namespace, key))
20671
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   397
        yield {'namespace': encoding.fromlocal(namespace),
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   398
               'key': encoding.fromlocal(key),
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   399
               'old': encoding.fromlocal(old),
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   400
               'new': encoding.fromlocal(new)}, f
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   401
        d = f.value
15652
ca6accdad79c wireproto: handle other server output in pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15585
diff changeset
   402
        d, output = d.split('\n', 1)
13450
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   403
        try:
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   404
            d = bool(int(d))
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   405
        except ValueError:
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   406
            raise error.ResponseError(
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   407
                _('push failed (unexpected response):'), d)
15652
ca6accdad79c wireproto: handle other server output in pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15585
diff changeset
   408
        for l in output.splitlines(True):
ca6accdad79c wireproto: handle other server output in pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15585
diff changeset
   409
            self.ui.status(_('remote: '), l)
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   410
        yield d
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   411
11588
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
   412
    def stream_out(self):
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
   413
        return self._callstream('stream_out')
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
   414
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   415
    def getbundle(self, source, **kwargs):
34739
b880cc11da5d wireproto: bounce kwargs to/from bytes/str as needed
Augie Fackler <augie@google.com>
parents: 34731
diff changeset
   416
        kwargs = pycompat.byteskwargs(kwargs)
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   417
        self.requirecap('getbundle', _('look up remote changes'))
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   418
        opts = {}
37412
1d459f61b42a wireproto: don't special case bundlecaps, but sort all scsv arguments
Joerg Sonnenberger <joerg@bec.de>
parents: 37393
diff changeset
   419
        bundlecaps = kwargs.get('bundlecaps') or set()
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   420
        for key, value in kwargs.iteritems():
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   421
            if value is None:
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   422
                continue
37613
96d735601ca1 wireproto: move gboptsmap to wireprototypes and rename (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37612
diff changeset
   423
            keytype = wireprototypes.GETBUNDLE_ARGUMENTS.get(key)
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   424
            if keytype is None:
34730
6be264009841 wireproto: use a proper exception instead of `assert False`
Augie Fackler <augie@google.com>
parents: 34729
diff changeset
   425
                raise error.ProgrammingError(
6be264009841 wireproto: use a proper exception instead of `assert False`
Augie Fackler <augie@google.com>
parents: 34729
diff changeset
   426
                    'Unexpectedly None keytype for key %s' % key)
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   427
            elif keytype == 'nodes':
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   428
                value = wireprototypes.encodelist(value)
37412
1d459f61b42a wireproto: don't special case bundlecaps, but sort all scsv arguments
Joerg Sonnenberger <joerg@bec.de>
parents: 37393
diff changeset
   429
            elif keytype == 'csv':
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   430
                value = ','.join(value)
37412
1d459f61b42a wireproto: don't special case bundlecaps, but sort all scsv arguments
Joerg Sonnenberger <joerg@bec.de>
parents: 37393
diff changeset
   431
            elif keytype == 'scsv':
1d459f61b42a wireproto: don't special case bundlecaps, but sort all scsv arguments
Joerg Sonnenberger <joerg@bec.de>
parents: 37393
diff changeset
   432
                value = ','.join(sorted(value))
21988
12cd3827b860 wireproto: add a ``boolean`` type for getbundle parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21728
diff changeset
   433
            elif keytype == 'boolean':
22351
7e6dd496d327 wireprotocol: fix 'boolean' handling
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
   434
                value = '%i' % bool(value)
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   435
            elif keytype != 'plain':
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   436
                raise KeyError('unknown getbundle option type %s'
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   437
                               % keytype)
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   438
            opts[key] = value
34739
b880cc11da5d wireproto: bounce kwargs to/from bytes/str as needed
Augie Fackler <augie@google.com>
parents: 34731
diff changeset
   439
        f = self._callcompressable("getbundle", **pycompat.strkwargs(opts))
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 25128
diff changeset
   440
        if any((cap.startswith('HG2') for cap in bundlecaps)):
24641
60fecc5b14a4 unbundle20: retrieve unbundler instances through a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23878
diff changeset
   441
            return bundle2.getunbundler(self.ui, f)
21069
0a9cae236738 bundle2: allow bundle2 for pulling over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21064
diff changeset
   442
        else:
22390
e2806b8613ca changegroup: rename bundle-related functions and classes
Sune Foldager <cryo@cyanite.org>
parents: 22353
diff changeset
   443
            return changegroupmod.cg1unpacker(f, 'UN')
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   444
37646
72e26319f3b8 wireproto: use command executor for unbundle
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37635
diff changeset
   445
    def unbundle(self, bundle, heads, url):
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   446
        '''Send cg (a readable file-like object representing the
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   447
        changegroup to push, typically a chunkbuffer object) to the
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   448
        remote server as a bundle.
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   449
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   450
        When pushing a bundle10 stream, return an integer indicating the
32880
4c2a46f89f08 wireproto: update reference to deleted addchangegroup()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32744
diff changeset
   451
        result of the push (see changegroup.apply()).
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   452
29706
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   453
        When pushing a bundle20 stream, return a bundle20 stream.
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   454
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   455
        `url` is the url the client thinks it's pushing to, which is
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   456
        visible to hooks.
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   457
        '''
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   458
14419
ede7cea1550f wireproto: do not hash when heads == ['force']
Martin Geisler <mg@aragost.com>
parents: 14093
diff changeset
   459
        if heads != ['force'] and self.capable('unbundlehash'):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   460
            heads = wireprototypes.encodelist(
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   461
                ['hashed', hashlib.sha1(''.join(sorted(heads))).digest()])
13942
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
   462
        else:
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   463
            heads = wireprototypes.encodelist(heads)
13942
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
   464
37646
72e26319f3b8 wireproto: use command executor for unbundle
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37635
diff changeset
   465
        if util.safehasattr(bundle, 'deltaheader'):
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   466
            # this a bundle10, do the old style call sequence
37646
72e26319f3b8 wireproto: use command executor for unbundle
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37635
diff changeset
   467
            ret, output = self._callpush("unbundle", bundle, heads=heads)
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   468
            if ret == "":
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   469
                raise error.ResponseError(
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   470
                    _('push failed:'), output)
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   471
            try:
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   472
                ret = int(ret)
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   473
            except ValueError:
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   474
                raise error.ResponseError(
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   475
                    _('push failed (unexpected response):'), ret)
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   476
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   477
            for l in output.splitlines(True):
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   478
                self.ui.status(_('remote: '), l)
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   479
        else:
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   480
            # bundle2 push. Send a stream, fetch a stream.
37646
72e26319f3b8 wireproto: use command executor for unbundle
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37635
diff changeset
   481
            stream = self._calltwowaystream('unbundle', bundle, heads=heads)
24641
60fecc5b14a4 unbundle20: retrieve unbundler instances through a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23878
diff changeset
   482
            ret = bundle2.getunbundler(self.ui, stream)
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   483
        return ret
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   484
37320
39f7d4ee8bcd repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37295
diff changeset
   485
    # End of ipeercommands interface.
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   486
37320
39f7d4ee8bcd repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37295
diff changeset
   487
    # Begin of ipeerlegacycommands interface.
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   488
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   489
    def branches(self, nodes):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   490
        n = wireprototypes.encodelist(nodes)
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   491
        d = self._call("branches", nodes=n)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   492
        try:
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   493
            br = [tuple(wireprototypes.decodelist(b)) for b in d.splitlines()]
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   494
            return br
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   495
        except ValueError:
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   496
            self._abort(error.ResponseError(_("unexpected response:"), d))
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   497
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   498
    def between(self, pairs):
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   499
        batch = 8 # avoid giant requests
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   500
        r = []
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38328
diff changeset
   501
        for i in pycompat.xrange(0, len(pairs), batch):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   502
            n = " ".join([wireprototypes.encodelist(p, '-')
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   503
                          for p in pairs[i:i + batch]])
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   504
            d = self._call("between", pairs=n)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   505
            try:
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   506
                r.extend(l and wireprototypes.decodelist(l) or []
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   507
                         for l in d.splitlines())
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   508
            except ValueError:
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   509
                self._abort(error.ResponseError(_("unexpected response:"), d))
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   510
        return r
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   511
37635
cc8c06835097 wireproto: convert legacy commands to command executor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37633
diff changeset
   512
    def changegroup(self, nodes, source):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   513
        n = wireprototypes.encodelist(nodes)
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   514
        f = self._callcompressable("changegroup", roots=n)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   515
        return changegroupmod.cg1unpacker(f, 'UN')
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   516
37635
cc8c06835097 wireproto: convert legacy commands to command executor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37633
diff changeset
   517
    def changegroupsubset(self, bases, heads, source):
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   518
        self.requirecap('changegroupsubset', _('look up remote changes'))
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   519
        bases = wireprototypes.encodelist(bases)
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   520
        heads = wireprototypes.encodelist(heads)
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   521
        f = self._callcompressable("changegroupsubset",
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   522
                                   bases=bases, heads=heads)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   523
        return changegroupmod.cg1unpacker(f, 'UN')
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   524
37320
39f7d4ee8bcd repository: port peer interfaces to zope.interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37295
diff changeset
   525
    # End of ipeerlegacycommands interface.
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   526
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   527
    def _submitbatch(self, req):
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   528
        """run batch request <req> on the server
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   529
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   530
        Returns an iterator of the raw responses from the server.
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   531
        """
36945
4901d1e22b27 peer-request: include more details about batch commands
Boris Feld <boris.feld@octobus.net>
parents: 36840
diff changeset
   532
        ui = self.ui
4901d1e22b27 peer-request: include more details about batch commands
Boris Feld <boris.feld@octobus.net>
parents: 36840
diff changeset
   533
        if ui.debugflag and ui.configbool('devel', 'debug.peer-request'):
4901d1e22b27 peer-request: include more details about batch commands
Boris Feld <boris.feld@octobus.net>
parents: 36840
diff changeset
   534
            ui.debug('devel-peer-request: batched-content\n')
4901d1e22b27 peer-request: include more details about batch commands
Boris Feld <boris.feld@octobus.net>
parents: 36840
diff changeset
   535
            for op, args in req:
4901d1e22b27 peer-request: include more details about batch commands
Boris Feld <boris.feld@octobus.net>
parents: 36840
diff changeset
   536
                msg = 'devel-peer-request:    - %s (%d arguments)\n'
4901d1e22b27 peer-request: include more details about batch commands
Boris Feld <boris.feld@octobus.net>
parents: 36840
diff changeset
   537
                ui.debug(msg % (op, len(args)))
4901d1e22b27 peer-request: include more details about batch commands
Boris Feld <boris.feld@octobus.net>
parents: 36840
diff changeset
   538
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   539
        unescapearg = wireprototypes.unescapebatcharg
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   540
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   541
        rsp = self._callstream("batch", cmds=encodebatchcmds(req))
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   542
        chunk = rsp.read(1024)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   543
        work = [chunk]
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   544
        while chunk:
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   545
            while ';' not in chunk and chunk:
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   546
                chunk = rsp.read(1024)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   547
                work.append(chunk)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   548
            merged = ''.join(work)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   549
            while ';' in merged:
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   550
                one, merged = merged.split(';', 1)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   551
                yield unescapearg(one)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   552
            chunk = rsp.read(1024)
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   553
            work = [merged, chunk]
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   554
        yield unescapearg(''.join(work))
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   555
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   556
    def _submitone(self, op, args):
34739
b880cc11da5d wireproto: bounce kwargs to/from bytes/str as needed
Augie Fackler <augie@google.com>
parents: 34731
diff changeset
   557
        return self._call(op, **pycompat.strkwargs(args))
33806
dedab036215d wireproto: use new peer interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33767
diff changeset
   558
14048
58e58406ed19 wireproto: add test for new optional arg missing on server
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13942
diff changeset
   559
    def debugwireargs(self, one, two, three=None, four=None, five=None):
13720
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   560
        # don't pass optional arguments left at their default value
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   561
        opts = {}
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   562
        if three is not None:
35374
7d2292416046 py3: handle keyword arguments correctly in wireproto.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35267
diff changeset
   563
            opts[r'three'] = three
13720
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   564
        if four is not None:
35374
7d2292416046 py3: handle keyword arguments correctly in wireproto.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35267
diff changeset
   565
            opts[r'four'] = four
13720
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   566
        return self._call('debugwireargs', one=one, two=two, **opts)
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   567
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   568
    def _call(self, cmd, **args):
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   569
        """execute <cmd> on the server
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   570
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   571
        The command is expected to return a simple string.
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   572
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   573
        returns the server reply as a string."""
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   574
        raise NotImplementedError()
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   575
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   576
    def _callstream(self, cmd, **args):
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   577
        """execute <cmd> on the server
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   578
28435
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   579
        The command is expected to return a stream. Note that if the
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   580
        command doesn't return a stream, _callstream behaves
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   581
        differently for ssh and http peers.
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   582
28435
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   583
        returns the server reply as a file like object.
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   584
        """
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   585
        raise NotImplementedError()
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   586
20905
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   587
    def _callcompressable(self, cmd, **args):
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   588
        """execute <cmd> on the server
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   589
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   590
        The command is expected to return a stream.
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   591
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20969
diff changeset
   592
        The stream may have been compressed in some implementations. This
20905
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   593
        function takes care of the decompression. This is the only difference
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   594
        with _callstream.
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   595
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   596
        returns the server reply as a file like object.
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   597
        """
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   598
        raise NotImplementedError()
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   599
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   600
    def _callpush(self, cmd, fp, **args):
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   601
        """execute a <cmd> on server
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   602
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   603
        The command is expected to be related to a push. Push has a special
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   604
        return method.
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   605
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   606
        returns the server reply as a (ret, output) tuple. ret is either
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   607
        empty (error) or a stringified int.
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   608
        """
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   609
        raise NotImplementedError()
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   610
21072
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   611
    def _calltwowaystream(self, cmd, fp, **args):
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   612
        """execute <cmd> on server
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   613
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   614
        The command will send a stream to the server and get a stream in reply.
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   615
        """
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   616
        raise NotImplementedError()
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   617
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   618
    def _abort(self, exception):
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   619
        """clearly abort the wire protocol connection and raise the exception
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   620
        """
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   621
        raise NotImplementedError()