# HG changeset patch # User Peter Arrenbrecht # Date 1308084980 -7200 # Node ID e7c9fdbbb9020424dcb0f26367a9b9c19b035a39 # Parent bd88561afb4b41c61d323bfff5ccb9d4a71791b8 wireproto: make a number of commands batchable Makes lookup, heads, known, branchmap, pushkey, and listkeys batchable. It could, for instance, be interesting to use this to batch calls to lookup when a pull or clone has multiple --rev arguments. The next patch is going to batch heads and known to slightly tune discovery. diff -r bd88561afb4b -r e7c9fdbbb902 mercurial/wireproto.py --- a/mercurial/wireproto.py Tue Jun 14 22:52:58 2011 +0200 +++ b/mercurial/wireproto.py Tue Jun 14 22:56:20 2011 +0200 @@ -161,31 +161,42 @@ def _submitone(self, op, args): return self._call(op, **args) + @batchable def lookup(self, key): self.requirecap('lookup', _('look up remote revision')) - d = self._call("lookup", key=encoding.fromlocal(key)) + f = future() + yield todict(key=encoding.fromlocal(key)), f + d = f.value success, data = d[:-1].split(" ", 1) if int(success): - return bin(data) + yield bin(data) self._abort(error.RepoError(data)) + @batchable def heads(self): - d = self._call("heads") + f = future() + yield {}, f + d = f.value try: - return decodelist(d[:-1]) + yield decodelist(d[:-1]) except ValueError: self._abort(error.ResponseError(_("unexpected response:"), d)) + @batchable def known(self, nodes): - n = encodelist(nodes) - d = self._call("known", nodes=n) + f = future() + yield todict(nodes=encodelist(nodes)), f + d = f.value try: - return [bool(int(f)) for f in d] + yield [bool(int(f)) for f in d] except ValueError: self._abort(error.ResponseError(_("unexpected response:"), d)) + @batchable def branchmap(self): - d = self._call("branchmap") + f = future() + yield {}, f + d = f.value try: branchmap = {} for branchpart in d.splitlines(): @@ -193,7 +204,7 @@ branchname = encoding.tolocal(urllib.unquote(branchname)) branchheads = decodelist(branchheads) branchmap[branchname] = branchheads - return branchmap + yield branchmap except TypeError: self._abort(error.ResponseError(_("unexpected response:"), d)) @@ -218,30 +229,35 @@ self._abort(error.ResponseError(_("unexpected response:"), d)) return r + @batchable def pushkey(self, namespace, key, old, new): if not self.capable('pushkey'): - return False - d = self._call("pushkey", - namespace=encoding.fromlocal(namespace), - key=encoding.fromlocal(key), - old=encoding.fromlocal(old), - new=encoding.fromlocal(new)) + yield False, None + f = future() + yield todict(namespace=encoding.fromlocal(namespace), + key=encoding.fromlocal(key), + old=encoding.fromlocal(old), + new=encoding.fromlocal(new)), f + d = f.value try: d = bool(int(d)) except ValueError: raise error.ResponseError( _('push failed (unexpected response):'), d) - return d + yield d + @batchable def listkeys(self, namespace): if not self.capable('pushkey'): - return {} - d = self._call("listkeys", namespace=encoding.fromlocal(namespace)) + yield {}, None + f = future() + yield todict(namespace=encoding.fromlocal(namespace)), f + d = f.value r = {} for l in d.splitlines(): k, v = l.split('\t') r[encoding.tolocal(k)] = encoding.tolocal(v) - return r + yield r def stream_out(self): return self._callstream('stream_out')