Mercurial > hg-stable
annotate mercurial/peer.py @ 34733:115efdd97088
peer: ensure command names are always ascii bytestrs
Differential Revision: https://phab.mercurial-scm.org/D1104
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 15 Oct 2017 00:05:00 -0400 |
parents | a652b7763f66 |
children |
rev | line source |
---|---|
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: |
33787
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33786
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:
33786
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 |