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
--- a/hgext/infinitepush/__init__.py Wed Apr 11 12:49:08 2018 -0700
+++ b/hgext/infinitepush/__init__.py Wed Apr 11 12:51:09 2018 -0700
@@ -120,7 +120,6 @@
extensions,
hg,
localrepo,
- peer,
phases,
pushkey,
pycompat,
@@ -354,11 +353,11 @@
else:
return orig(self, namespace)
-@peer.batchable
+@wireprotov1peer.batchable
def listkeyspatterns(self, namespace, patterns):
if not self.capable('pushkey'):
yield {}, None
- f = peer.future()
+ f = wireprotov1peer.future()
self.ui.debug('preparing listkeys for "%s" with pattern "%s"\n' %
(namespace, patterns))
yield {
--- a/mercurial/localrepo.py Wed Apr 11 12:49:08 2018 -0700
+++ b/mercurial/localrepo.py Wed Apr 11 12:51:09 2018 -0700
@@ -49,7 +49,6 @@
narrowspec,
obsolete,
pathutil,
- peer,
phases,
pushkey,
pycompat,
@@ -66,6 +65,7 @@
txnutil,
util,
vfs as vfsmod,
+ wireprotov1peer,
)
from .utils import (
procutil,
@@ -153,6 +153,20 @@
'unbundle'}
legacycaps = moderncaps.union({'changegroupsubset'})
+class localiterbatcher(wireprotov1peer.iterbatcher):
+ def __init__(self, local):
+ super(localiterbatcher, self).__init__()
+ self.local = local
+
+ def submit(self):
+ # submit for a local iter batcher is a noop
+ pass
+
+ def results(self):
+ for name, args, opts, resref in self.calls:
+ resref.set(getattr(self.local, name)(*args, **opts))
+ yield resref.value
+
class localpeer(repository.peer):
'''peer for a local repo; reflects only the most recent API'''
@@ -273,7 +287,7 @@
# Begin of peer interface.
def iterbatch(self):
- return peer.localiterbatcher(self)
+ return localiterbatcher(self)
# End of peer interface.
--- a/mercurial/peer.py Wed Apr 11 12:49:08 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-# peer.py - repository base classes for mercurial
-#
-# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
-# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-from __future__ import absolute_import
-
-from . import (
- error,
- pycompat,
- util,
-)
-
-# 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()
- # 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 localiterbatcher(iterbatcher):
- def __init__(self, local):
- super(iterbatcher, self).__init__()
- self.local = local
-
- def submit(self):
- # submit for a local iter batcher is a noop
- pass
-
- def results(self):
- for name, args, opts, resref in self.calls:
- resref.set(getattr(self.local, name)(*args, **opts))
- yield resref.value
-
-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
--- 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
--- a/tests/test-batching.py Wed Apr 11 12:49:08 2018 -0700
+++ b/tests/test-batching.py Wed Apr 11 12:51:09 2018 -0700
@@ -9,9 +9,10 @@
from mercurial import (
error,
- peer,
+ localrepo,
util,
wireprotov1peer,
+
)
# equivalent of repo.repository
@@ -31,7 +32,7 @@
return "Hello, %s" % name
def batchiter(self):
'''Support for local batching.'''
- return peer.localiterbatcher(self)
+ return localrepo.localiterbatcher(self)
# usage of "thing" interface
def use(it):
@@ -51,7 +52,7 @@
bar2 = batch.bar(b="Uno", a="Due")
# Future shouldn't be set until we submit().
- assert isinstance(foo, peer.future)
+ assert isinstance(foo, wireprotov1peer.future)
assert not util.safehasattr(foo, 'value')
assert not util.safehasattr(bar, 'value')
batch.submit()
@@ -179,16 +180,16 @@
def batchiter(self):
return wireprotov1peer.remoteiterbatcher(self)
- @peer.batchable
+ @wireprotov1peer.batchable
def foo(self, one, two=None):
encargs = [('one', mangle(one),), ('two', mangle(two),)]
- encresref = peer.future()
+ encresref = wireprotov1peer.future()
yield encargs, encresref
yield unmangle(encresref.value)
- @peer.batchable
+ @wireprotov1peer.batchable
def bar(self, b, a):
- encresref = peer.future()
+ encresref = wireprotov1peer.future()
yield [('b', mangle(b),), ('a', mangle(a),)], encresref
yield unmangle(encresref.value)