# HG changeset patch # User Martin von Zweigbergk # Date 2018-09-20 00:34:36 # Node ID d8a7690ccc7401b7e1e01aaee47914d7bd42ad9e # Parent 491fc3f4be673f1aed563aeb89ffd46718f3cd68 fastannotate: process files as they arrive peer.commandexecutor()'s context manager waits for all responses to arrive in its __exit__() method. We want to process the results as they arrive, so we should do that inside the context manager scope. Note that the futures' result() methods have been replaced to make sure that the command executor's sendcommands() method is called when the first future's result is requested, so we don't need to do that. A minor side-effect is that we can no longer easily tell when the server has started sending us responses, so that long statement was lost. Differential Revision: https://phab.mercurial-scm.org/D4666 diff --git a/hgext/fastannotate/protocol.py b/hgext/fastannotate/protocol.py --- a/hgext/fastannotate/protocol.py +++ b/hgext/fastannotate/protocol.py @@ -163,23 +163,23 @@ def clientfetch(repo, paths, lastnodemap 'getannotate', {'path': p, 'lastnode':lastnodemap.get(p)})) - ui.debug('fastannotate: server returned\n') - for result in results: - r = result.result() - # TODO: pconvert these paths on the server? - r = {util.pconvert(p): v for p, v in r.iteritems()} - for path in sorted(r): - # ignore malicious paths - if not path.startswith('fastannotate/') or '/../' in (path + '/'): - ui.debug('fastannotate: ignored malicious path %s\n' % path) - continue - content = r[path] - if ui.debugflag: - ui.debug('fastannotate: writing %d bytes to %s\n' - % (len(content), path)) - repo.vfs.makedirs(os.path.dirname(path)) - with repo.vfs(path, 'wb') as f: - f.write(content) + for result in results: + r = result.result() + # TODO: pconvert these paths on the server? + r = {util.pconvert(p): v for p, v in r.iteritems()} + for path in sorted(r): + # ignore malicious paths + if (not path.startswith('fastannotate/') + or '/../' in (path + '/')): + ui.debug('fastannotate: ignored malicious path %s\n' % path) + continue + content = r[path] + if ui.debugflag: + ui.debug('fastannotate: writing %d bytes to %s\n' + % (len(content), path)) + repo.vfs.makedirs(os.path.dirname(path)) + with repo.vfs(path, 'wb') as f: + f.write(content) def _filterfetchpaths(repo, paths): """return a subset of paths whose history is long and need to fetch linelog diff --git a/tests/test-fastannotate-protocol.t b/tests/test-fastannotate-protocol.t --- a/tests/test-fastannotate-protocol.t +++ b/tests/test-fastannotate-protocol.t @@ -47,7 +47,6 @@ setup the local repo sending protocaps command fastannotate: requesting 1 files sending getannotate command - fastannotate: server returned fastannotate: writing 112 bytes to fastannotate/default/a.l fastannotate: writing 94 bytes to fastannotate/default/a.m fastannotate: a: using fast path (resolved fctx: True) @@ -94,7 +93,6 @@ client can also build things up on its o sending protocaps command fastannotate: requesting 1 files sending getannotate command - fastannotate: server returned fastannotate: a: 1 new changesets in the main branch 0: 1 1: 2 @@ -142,7 +140,6 @@ in the "fctx" mode, the client could als $ hg annotate a --config fastannotate.modes=fctx --debug --config fastannotate.mainbranch=4 | grep fastannotate fastannotate: requesting 1 files - fastannotate: server returned fastannotate: a: 1 new changesets in the main branch the server would rebuild broken cache automatically @@ -171,7 +168,6 @@ use the "debugbuildannotatecache" comman sending protocaps command fastannotate: requesting 1 files sending getannotate command - fastannotate: server returned fastannotate: writing * (glob) fastannotate: writing * (glob) $ diff $p1/a.l $p2/a.l