Patchwork D2408: debugcommands: support for sending "batch" requests

login
register
mail settings
Submitter phabricator
Date Feb. 26, 2018, 9:17 p.m.
Message ID <e05e639ddef4dcb177c114b1d152a62f@localhost.localdomain>
Download mbox | patch
Permalink /patch/28429/
State Not Applicable
Headers show

Comments

phabricator - Feb. 26, 2018, 9:17 p.m.
indygreg updated this revision to Diff 6142.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2408?vs=6027&id=6142

REVISION DETAIL
  https://phab.mercurial-scm.org/D2408

AFFECTED FILES
  mercurial/debugcommands.py
  tests/test-ssh-proto.t

CHANGE DETAILS




To: indygreg, #hg-reviewers
Cc: mercurial-devel

Patch

diff --git a/tests/test-ssh-proto.t b/tests/test-ssh-proto.t
--- a/tests/test-ssh-proto.t
+++ b/tests/test-ssh-proto.t
@@ -1830,3 +1830,105 @@ 
   o>     15\n
   o> bufferedread(15) -> 15: publishing	True
   response: publishing	True
+
+  $ cd ..
+
+Test batching of requests
+
+  $ hg init batching
+  $ cd batching
+  $ echo 0 > foo
+  $ hg add foo
+  $ hg -q commit -m initial
+  $ hg phase --public
+  $ echo 1 > foo
+  $ hg commit -m 'commit 1'
+  $ hg -q up 0
+  $ echo 2 > foo
+  $ hg commit -m 'commit 2'
+  created new head
+  $ hg book -r 1 bookA
+  $ hg book -r 2 bookB
+
+  $ debugwireproto << EOF
+  > batchbegin
+  > command heads
+  > command listkeys
+  >     namespace bookmarks
+  > command listkeys
+  >     namespace phases
+  > batchsubmit
+  > EOF
+  testing ssh1
+  creating ssh peer from handshake results
+  i> write(104) -> None:
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 4:
+  o>     384\n
+  o> readline() -> 384:
+  o>     capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN\n
+  o> readline() -> 2:
+  o>     1\n
+  o> readline() -> 1:
+  o>     \n
+  sending batch with 3 sub-commands
+  i> write(6) -> None:
+  i>     batch\n
+  i> write(4) -> None:
+  i>     * 0\n
+  i> write(8) -> None:
+  i>     cmds 61\n
+  i> write(61) -> None: heads ;listkeys namespace=bookmarks;listkeys namespace=phases
+  i> flush() -> None
+  o> bufferedreadline() -> 4:
+  o>     278\n
+  o> bufferedread(278) -> 278:
+  o>     bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
+  o>     ;bookA	4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
+  o>     bookB	bfebe6bd38eebc6f8202e419c1171268987ea6a6;4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab	1\n
+  o>     bfebe6bd38eebc6f8202e419c1171268987ea6a6	1\n
+  o>     publishing	True
+  response #0: bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
+  response #1: bookA	4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\nbookB	bfebe6bd38eebc6f8202e419c1171268987ea6a6
+  response #2: 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab	1\nbfebe6bd38eebc6f8202e419c1171268987ea6a6	1\npublishing	True
+  
+  testing ssh2
+  creating ssh peer from handshake results
+  i> write(171) -> None:
+  i>     upgrade * proto=exp-ssh-v2-0001\n (glob)
+  i>     hello\n
+  i>     between\n
+  i>     pairs 81\n
+  i>     0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
+  i> flush() -> None
+  o> readline() -> 62:
+  o>     upgraded * exp-ssh-v2-0001\n (glob)
+  o> readline() -> 4:
+  o>     383\n
+  o> read(383) -> 383: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN
+  o> read(1) -> 1:
+  o>     \n
+  sending batch with 3 sub-commands
+  i> write(6) -> None:
+  i>     batch\n
+  i> write(4) -> None:
+  i>     * 0\n
+  i> write(8) -> None:
+  i>     cmds 61\n
+  i> write(61) -> None: heads ;listkeys namespace=bookmarks;listkeys namespace=phases
+  i> flush() -> None
+  o> bufferedreadline() -> 4:
+  o>     278\n
+  o> bufferedread(278) -> 278:
+  o>     bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
+  o>     ;bookA	4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
+  o>     bookB	bfebe6bd38eebc6f8202e419c1171268987ea6a6;4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab	1\n
+  o>     bfebe6bd38eebc6f8202e419c1171268987ea6a6	1\n
+  o>     publishing	True
+  response #0: bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
+  response #1: bookA	4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\nbookB	bfebe6bd38eebc6f8202e419c1171268987ea6a6
+  response #2: 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab	1\nbfebe6bd38eebc6f8202e419c1171268987ea6a6	1\npublishing	True
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -2629,6 +2629,21 @@ 
     Values are interpreted as Python b'' literals. This allows encoding
     special byte sequences via backslash escaping.
 
+    batchbegin
+    ----------
+
+    Instruct the peer to begin a batched send.
+
+    All ``command`` blocks are queued for execution until the next
+    ``batchsubmit`` block.
+
+    batchsubmit
+    -----------
+
+    Submit previously queued ``command`` blocks as a batch request.
+
+    This action MUST be paired with a ``batchbegin`` action.
+
     close
     -----
 
@@ -2714,6 +2729,8 @@ 
     else:
         raise error.Abort(_('only --localssh is currently supported'))
 
+    batchedcommands = None
+
     # Now perform actions based on the parsed wire language instructions.
     for action, lines in blocks:
         if action in ('raw', 'raw+'):
@@ -2738,10 +2755,29 @@ 
                 key, value = line.lstrip().split(' ', 1)
                 args[key] = ast.literal_eval(b'b"%s"' % value)
 
+            if batchedcommands is not None:
+                batchedcommands.append((command, args))
+                continue
+
             ui.status(_('sending %s command\n') % command)
             res = peer._call(command, **args)
             ui.status(_('response: %s\n') % util.escapedata(res))
 
+        elif action == 'batchbegin':
+            if batchedcommands is not None:
+                raise error.Abort(_('nested batchbegin not allowed'))
+
+            batchedcommands = []
+        elif action == 'batchsubmit':
+            # There is a batching API we could go through. But it would be
+            # difficult to normalize requests into function calls. It is easier
+            # to bypass this layer and normalize to commands + args.
+            ui.status(_('sending batch with %d sub-commands\n') %
+                      len(batchedcommands))
+            for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
+                ui.status(_('response #%d: %s\n') % (i, util.escapedata(chunk)))
+
+            batchedcommands = None
         elif action == 'close':
             peer.close()
         elif action == 'readavailable':
@@ -2756,6 +2792,9 @@ 
         else:
             raise error.Abort(_('unknown action: %s') % action)
 
+    if batchedcommands is not None:
+        raise error.Abort(_('unclosed "batchbegin" request'))
+
     if peer:
         peer.close()