Mercurial > hg
comparison mercurial/wireprotov1peer.py @ 37615:f3dc8239e3a9
peer: scatter module to the wind (API)
peer.py hardly contained any code. The code it did contain was
generic to the version 1 peer interface or specific to the
local repository peer.
So code has been moved to wireprotov1peer and localrepo, as
appropriate.
Differential Revision: https://phab.mercurial-scm.org/D3260
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 11 Apr 2018 12:51:09 -0700 |
parents | a81d02ea65db |
children | e1b32dc4646c |
comparison
equal
deleted
inserted
replaced
37614:a81d02ea65db | 37615:f3dc8239e3a9 |
---|---|
17 from . import ( | 17 from . import ( |
18 bundle2, | 18 bundle2, |
19 changegroup as changegroupmod, | 19 changegroup as changegroupmod, |
20 encoding, | 20 encoding, |
21 error, | 21 error, |
22 peer, | |
23 pushkey as pushkeymod, | 22 pushkey as pushkeymod, |
24 pycompat, | 23 pycompat, |
25 repository, | 24 repository, |
26 util, | 25 util, |
27 wireprototypes, | 26 wireprototypes, |
28 ) | 27 ) |
29 | 28 |
30 urlreq = util.urlreq | 29 urlreq = util.urlreq |
31 | 30 |
32 class remoteiterbatcher(peer.iterbatcher): | 31 def batchable(f): |
32 '''annotation for batchable methods | |
33 | |
34 Such methods must implement a coroutine as follows: | |
35 | |
36 @batchable | |
37 def sample(self, one, two=None): | |
38 # Build list of encoded arguments suitable for your wire protocol: | |
39 encargs = [('one', encode(one),), ('two', encode(two),)] | |
40 # Create future for injection of encoded result: | |
41 encresref = future() | |
42 # Return encoded arguments and future: | |
43 yield encargs, encresref | |
44 # Assuming the future to be filled with the result from the batched | |
45 # request now. Decode it: | |
46 yield decode(encresref.value) | |
47 | |
48 The decorator returns a function which wraps this coroutine as a plain | |
49 method, but adds the original method as an attribute called "batchable", | |
50 which is used by remotebatch to split the call into separate encoding and | |
51 decoding phases. | |
52 ''' | |
53 def plain(*args, **opts): | |
54 batchable = f(*args, **opts) | |
55 encargsorres, encresref = next(batchable) | |
56 if not encresref: | |
57 return encargsorres # a local result in this case | |
58 self = args[0] | |
59 cmd = pycompat.bytesurl(f.__name__) # ensure cmd is ascii bytestr | |
60 encresref.set(self._submitone(cmd, encargsorres)) | |
61 return next(batchable) | |
62 setattr(plain, 'batchable', f) | |
63 return plain | |
64 | |
65 class future(object): | |
66 '''placeholder for a value to be set later''' | |
67 def set(self, value): | |
68 if util.safehasattr(self, 'value'): | |
69 raise error.RepoError("future is already set") | |
70 self.value = value | |
71 | |
72 class batcher(object): | |
73 '''base class for batches of commands submittable in a single request | |
74 | |
75 All methods invoked on instances of this class are simply queued and | |
76 return a a future for the result. Once you call submit(), all the queued | |
77 calls are performed and the results set in their respective futures. | |
78 ''' | |
79 def __init__(self): | |
80 self.calls = [] | |
81 def __getattr__(self, name): | |
82 def call(*args, **opts): | |
83 resref = future() | |
84 # Please don't invent non-ascii method names, or you will | |
85 # give core hg a very sad time. | |
86 self.calls.append((name.encode('ascii'), args, opts, resref,)) | |
87 return resref | |
88 return call | |
89 def submit(self): | |
90 raise NotImplementedError() | |
91 | |
92 class iterbatcher(batcher): | |
93 | |
94 def submit(self): | |
95 raise NotImplementedError() | |
96 | |
97 def results(self): | |
98 raise NotImplementedError() | |
99 | |
100 class remoteiterbatcher(iterbatcher): | |
33 def __init__(self, remote): | 101 def __init__(self, remote): |
34 super(remoteiterbatcher, self).__init__() | 102 super(remoteiterbatcher, self).__init__() |
35 self._remote = remote | 103 self._remote = remote |
36 | 104 |
37 def __getattr__(self, name): | 105 def __getattr__(self, name): |
89 else: | 157 else: |
90 raise error.ProgrammingError('%s @batchable generator emitted ' | 158 raise error.ProgrammingError('%s @batchable generator emitted ' |
91 'unexpected value count' % command) | 159 'unexpected value count' % command) |
92 | 160 |
93 yield finalfuture.value | 161 yield finalfuture.value |
94 | |
95 # Forward a couple of names from peer to make wireproto interactions | |
96 # slightly more sensible. | |
97 batchable = peer.batchable | |
98 future = peer.future | |
99 | 162 |
100 def encodebatchcmds(req): | 163 def encodebatchcmds(req): |
101 """Return a ``cmds`` argument value for the ``batch`` command.""" | 164 """Return a ``cmds`` argument value for the ``batch`` command.""" |
102 escapearg = wireprototypes.escapebatcharg | 165 escapearg = wireprototypes.escapebatcharg |
103 | 166 |