Mercurial > hg-stable
changeset 28436:8d38eab2777a
peer: add an iterbatcher interface
This is very much like ordinary batch(), but it will let me add a mode
for batch where we have pathologically large requests which are then
handled streamily. This will be a significant improvement for things
like remotefilelog, which may want to request thousands of entities at
once.
author | Augie Fackler <augie@google.com> |
---|---|
date | Tue, 01 Mar 2016 18:39:25 -0500 |
parents | 176736afa886 |
children | c3eacee01c7e |
files | mercurial/peer.py mercurial/wireproto.py |
diffstat | 2 files changed, 51 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/peer.py Wed Mar 02 14:18:43 2016 -0500 +++ b/mercurial/peer.py Tue Mar 01 18:39:25 2016 -0500 @@ -41,6 +41,14 @@ def submit(self): raise NotImplementedError() +class iterbatcher(batcher): + + def submit(self): + raise NotImplementedError() + + def results(self): + raise NotImplementedError() + class localbatch(batcher): '''performs the queued calls directly''' def __init__(self, local): @@ -50,6 +58,19 @@ for name, args, opts, resref in self.calls: resref.set(getattr(self.local, name)(*args, **opts)) +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: + yield getattr(self.local, name)(*args, **opts) + def batchable(f): '''annotation for batchable methods @@ -91,6 +112,14 @@ def batch(self): return localbatch(self) + def iterbatch(self): + """Batch requests but allow iterating over the results. + + This is to allow interleaving responses with things like + progress updates for clients. + """ + return localiterbatcher(self) + def capable(self, name): '''tell whether repo supports named capability. return False if not supported.
--- a/mercurial/wireproto.py Wed Mar 02 14:18:43 2016 -0500 +++ b/mercurial/wireproto.py Tue Mar 01 18:39:25 2016 -0500 @@ -114,6 +114,25 @@ encresref.set(encres) resref.set(batchable.next()) +class remoteiterbatcher(peer.iterbatcher): + def __init__(self, remote): + super(remoteiterbatcher, self).__init__() + self._remote = remote + + def submit(self): + """Break the batch request into many patch calls and pipeline them. + + This is mostly valuable over http where request sizes can be + limited, but can be used in other places as well. + """ + rb = self._remote.batch() + rb.calls = self.calls + rb.submit() + + def results(self): + for name, args, opts, resref in self.calls: + yield resref.value + # Forward a couple of names from peer to make wireproto interactions # slightly more sensible. batchable = peer.batchable @@ -193,6 +212,9 @@ def _submitone(self, op, args): return self._call(op, **args) + def iterbatch(self): + return remoteiterbatcher(self) + @batchable def lookup(self, key): self.requirecap('lookup', _('look up remote revision'))