--- a/mercurial/wireproto.py Mon Aug 03 06:13:05 2015 -0700
+++ b/mercurial/wireproto.py Wed Aug 05 14:51:34 2015 -0400
@@ -58,48 +58,12 @@
Some protocols may have compressed the contents."""
raise NotImplementedError()
-# abstract batching support
-
-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()
- self.calls.append((name, args, opts, resref,))
- return resref
- return call
- def submit(self):
- pass
-
-class localbatch(batcher):
- '''performs the queued calls directly'''
- def __init__(self, local):
- batcher.__init__(self)
- self.local = local
- def submit(self):
- for name, args, opts, resref in self.calls:
- resref.set(getattr(self.local, name)(*args, **opts))
-
-class remotebatch(batcher):
+class remotebatch(peer.batcher):
'''batches the queued calls; uses as few roundtrips as possible'''
def __init__(self, remote):
'''remote must support _submitbatch(encbatch) and
_submitone(op, encargs)'''
- batcher.__init__(self)
+ peer.batcher.__init__(self)
self.remote = remote
def submit(self):
req, rsp = [], []
@@ -128,41 +92,10 @@
encresref.set(encres)
resref.set(batchable.next())
-def batchable(f):
- '''annotation for batchable methods
-
- Such methods must implement a coroutine as follows:
-
- @batchable
- def sample(self, one, two=None):
- # Handle locally computable results first:
- if not one:
- yield "a local result", 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 = batchable.next()
- if not encresref:
- return encargsorres # a local result in this case
- self = args[0]
- encresref.set(self._submitone(f.func_name, encargsorres))
- return batchable.next()
- setattr(plain, 'batchable', f)
- return plain
+# Forward a couple of names from peer to make wireproto interactions
+# slightly more sensible.
+batchable = peer.batchable
+future = peer.future
# list of nodes encoding / decoding