mercurial/peer.py
author Gregory Szorc <gregory.szorc@gmail.com>
Sun, 11 Mar 2018 15:40:58 -0700
changeset 36907 c1de7efca574
parent 34733 115efdd97088
permissions -rw-r--r--
hgweb: port to new response API These were the last consumers of wsgirequest.respond() \o/ Differential Revision: https://phab.mercurial-scm.org/D2829
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
17192
1ac628cd7113 peer: introduce real peer classes
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 17191
diff changeset
     1
# peer.py - repository base classes for mercurial
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents:
diff changeset
     2
#
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3930
diff changeset
     3
# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
2859
345bac2bc4ec update copyrights.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2612
diff changeset
     4
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents:
diff changeset
     5
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7873
diff changeset
     6
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9436
diff changeset
     7
# GNU General Public License version 2 or any later version.
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents:
diff changeset
     8
25965
e6b56b2c1f26 peer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25912
diff changeset
     9
from __future__ import absolute_import
e6b56b2c1f26 peer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25912
diff changeset
    10
e6b56b2c1f26 peer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25912
diff changeset
    11
from . import (
e6b56b2c1f26 peer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25912
diff changeset
    12
    error,
34733
115efdd97088 peer: ensure command names are always ascii bytestrs
Augie Fackler <augie@google.com>
parents: 34727
diff changeset
    13
    pycompat,
25965
e6b56b2c1f26 peer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25912
diff changeset
    14
    util,
e6b56b2c1f26 peer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25912
diff changeset
    15
)
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    16
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    17
# abstract batching support
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    18
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    19
class future(object):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    20
    '''placeholder for a value to be set later'''
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    21
    def set(self, value):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    22
        if util.safehasattr(self, 'value'):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    23
            raise error.RepoError("future is already set")
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    24
        self.value = value
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    25
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    26
class batcher(object):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    27
    '''base class for batches of commands submittable in a single request
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    28
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    29
    All methods invoked on instances of this class are simply queued and
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    30
    return a a future for the result. Once you call submit(), all the queued
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    31
    calls are performed and the results set in their respective futures.
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    32
    '''
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    33
    def __init__(self):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    34
        self.calls = []
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    35
    def __getattr__(self, name):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    36
        def call(*args, **opts):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    37
            resref = future()
34727
a652b7763f66 peer: when collecting method names for batch calls, bytes-ify __name__
Augie Fackler <augie@google.com>
parents: 34693
diff changeset
    38
            # Please don't invent non-ascii method names, or you will
a652b7763f66 peer: when collecting method names for batch calls, bytes-ify __name__
Augie Fackler <augie@google.com>
parents: 34693
diff changeset
    39
            # give core hg a very sad time.
a652b7763f66 peer: when collecting method names for batch calls, bytes-ify __name__
Augie Fackler <augie@google.com>
parents: 34693
diff changeset
    40
            self.calls.append((name.encode('ascii'), args, opts, resref,))
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    41
            return resref
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    42
        return call
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    43
    def submit(self):
28434
d549cbb5503d peer: raise NotImplementedError for abstract submit() method
Augie Fackler <augie@google.com>
parents: 25965
diff changeset
    44
        raise NotImplementedError()
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    45
28436
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    46
class iterbatcher(batcher):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    47
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    48
    def submit(self):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    49
        raise NotImplementedError()
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    50
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    51
    def results(self):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    52
        raise NotImplementedError()
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    53
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    54
class localiterbatcher(iterbatcher):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    55
    def __init__(self, local):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    56
        super(iterbatcher, self).__init__()
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    57
        self.local = local
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    58
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    59
    def submit(self):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    60
        # submit for a local iter batcher is a noop
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    61
        pass
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    62
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    63
    def results(self):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    64
        for name, args, opts, resref in self.calls:
33766
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    65
            resref.set(getattr(self.local, name)(*args, **opts))
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33765
diff changeset
    66
            yield resref.value
28436
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
    67
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    68
def batchable(f):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    69
    '''annotation for batchable methods
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    70
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    71
    Such methods must implement a coroutine as follows:
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    72
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    73
    @batchable
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    74
    def sample(self, one, two=None):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    75
        # Build list of encoded arguments suitable for your wire protocol:
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    76
        encargs = [('one', encode(one),), ('two', encode(two),)]
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    77
        # Create future for injection of encoded result:
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    78
        encresref = future()
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    79
        # Return encoded arguments and future:
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    80
        yield encargs, encresref
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    81
        # Assuming the future to be filled with the result from the batched
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    82
        # request now. Decode it:
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    83
        yield decode(encresref.value)
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    84
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    85
    The decorator returns a function which wraps this coroutine as a plain
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    86
    method, but adds the original method as an attribute called "batchable",
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    87
    which is used by remotebatch to split the call into separate encoding and
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    88
    decoding phases.
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    89
    '''
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    90
    def plain(*args, **opts):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    91
        batchable = f(*args, **opts)
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 28436
diff changeset
    92
        encargsorres, encresref = next(batchable)
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    93
        if not encresref:
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    94
            return encargsorres # a local result in this case
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    95
        self = args[0]
34733
115efdd97088 peer: ensure command names are always ascii bytestrs
Augie Fackler <augie@google.com>
parents: 34727
diff changeset
    96
        cmd = pycompat.bytesurl(f.__name__)  # ensure cmd is ascii bytestr
115efdd97088 peer: ensure command names are always ascii bytestrs
Augie Fackler <augie@google.com>
parents: 34727
diff changeset
    97
        encresref.set(self._submitone(cmd, encargsorres))
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 28436
diff changeset
    98
        return next(batchable)
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
    99
    setattr(plain, 'batchable', f)
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
   100
    return plain