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