Mercurial > hg
diff 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 |
line wrap: on
line diff
--- a/mercurial/wireprotov1peer.py Wed Apr 11 12:49:08 2018 -0700 +++ b/mercurial/wireprotov1peer.py Wed Apr 11 12:51:09 2018 -0700 @@ -19,7 +19,6 @@ changegroup as changegroupmod, encoding, error, - peer, pushkey as pushkeymod, pycompat, repository, @@ -29,7 +28,76 @@ urlreq = util.urlreq -class remoteiterbatcher(peer.iterbatcher): +def batchable(f): + '''annotation for batchable methods + + Such methods must implement a coroutine as follows: + + @batchable + def sample(self, one, two=None): + # Build list of encoded arguments suitable for your wire protocol: + encargs = [('one', encode(one),), ('two', encode(two),)] + # Create future for injection of encoded result: + encresref = future() + # Return encoded arguments and future: + yield encargs, encresref + # Assuming the future to be filled with the result from the batched + # request now. Decode it: + yield decode(encresref.value) + + The decorator returns a function which wraps this coroutine as a plain + method, but adds the original method as an attribute called "batchable", + which is used by remotebatch to split the call into separate encoding and + decoding phases. + ''' + def plain(*args, **opts): + batchable = f(*args, **opts) + encargsorres, encresref = next(batchable) + if not encresref: + return encargsorres # a local result in this case + self = args[0] + cmd = pycompat.bytesurl(f.__name__) # ensure cmd is ascii bytestr + encresref.set(self._submitone(cmd, encargsorres)) + return next(batchable) + setattr(plain, 'batchable', f) + return plain + +class future(object): + '''placeholder for a value to be set later''' + def set(self, value): + if util.safehasattr(self, 'value'): + raise error.RepoError("future is already set") + self.value = value + +class batcher(object): + '''base class for batches of commands submittable in a single request + + All methods invoked on instances of this class are simply queued and + return a a future for the result. Once you call submit(), all the queued + calls are performed and the results set in their respective futures. + ''' + def __init__(self): + self.calls = [] + def __getattr__(self, name): + def call(*args, **opts): + resref = future() + # Please don't invent non-ascii method names, or you will + # give core hg a very sad time. + self.calls.append((name.encode('ascii'), args, opts, resref,)) + return resref + return call + def submit(self): + raise NotImplementedError() + +class iterbatcher(batcher): + + def submit(self): + raise NotImplementedError() + + def results(self): + raise NotImplementedError() + +class remoteiterbatcher(iterbatcher): def __init__(self, remote): super(remoteiterbatcher, self).__init__() self._remote = remote @@ -92,11 +160,6 @@ yield finalfuture.value -# Forward a couple of names from peer to make wireproto interactions -# slightly more sensible. -batchable = peer.batchable -future = peer.future - def encodebatchcmds(req): """Return a ``cmds`` argument value for the ``batch`` command.""" escapearg = wireprototypes.escapebatcharg