author | Gregory Szorc <gregory.szorc@gmail.com> |
Sun, 11 Feb 2018 16:30:44 -0800 | |
changeset 36113 | a42817fede27 |
parent 34733 | 115efdd97088 |
permissions | -rw-r--r-- |
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 | 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 | 4 |
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> |
1089 | 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 | 7 |
# GNU General Public License version 2 or any later version. |
1089 | 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 |