Mercurial > hg
annotate tests/test-batching.py @ 37048:fc5e261915b9
wireproto: require POST for all HTTPv2 requests
Wire protocol version 1 transfers argument data via request
headers by default. This has historically caused problems because
servers institute limits on the length of individual HTTP headers
as well as the total size of all request headers. Mercurial servers
can advertise the maximum length of an individual header. But
there's no guarantee any intermediate HTTP agents will accept
headers up to that length.
In the existing wire protocol, server operators typically also
key off the HTTP request method to implement authentication.
For example, GET requests translate to read-only requests and
can be allowed. But read-write commands must use POST and require
authentication. This has typically worked because the only wire
protocol commands that use POST modify the repo (e.g. the
"unbundle" command).
There is an experimental feature to enable clients to transmit
argument data via POST request bodies. This is technically a
better and more robust solution. But we can't enable it by default
because of servers assuming POST means write access.
In version 2 of the wire protocol, the permissions of a request
are encoded in the URL. And with it being a new protocol in a new
URL space, we're not constrained by backwards compatibility
requirements.
This commit adopts the technically superior mechanism of using
HTTP request bodies to send argument data by requiring POST for
all commands. Strictly speaking, it may be possible to send
request bodies on GET requests. But my experience is that not all
HTTP stacks support this. POST pretty much always works. Using POST
for read-only operations does sacrifice some RESTful design
purity. But this API cares about practicality, not about being
in Roy T. Fielding's REST ivory tower.
There's a chance we may relax this restriction in the future. But
for now, I want to see how far we can get with a POST only API.
Differential Revision: https://phab.mercurial-scm.org/D2837
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Tue, 13 Mar 2018 11:57:43 -0700 |
parents | 4c706037adef |
children | a81d02ea65db |
rev | line source |
---|---|
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
1 # test-batching.py - tests for transparent command batching |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
2 # |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
3 # Copyright 2011 Peter Arrenbrecht <peter@arrenbrecht.ch> |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
4 # |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
7 |
28732
e2b118592c63
py3: use print_function in test-batching.py
Robert Stanca <robert.stanca7@gmail.com>
parents:
28731
diff
changeset
|
8 from __future__ import absolute_import, print_function |
28800
544908ae36ce
test-batching: stop direct symbol import of mercurial modules
Yuya Nishihara <yuya@tcha.org>
parents:
28732
diff
changeset
|
9 |
544908ae36ce
test-batching: stop direct symbol import of mercurial modules
Yuya Nishihara <yuya@tcha.org>
parents:
28732
diff
changeset
|
10 from mercurial import ( |
33766
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
11 error, |
28800
544908ae36ce
test-batching: stop direct symbol import of mercurial modules
Yuya Nishihara <yuya@tcha.org>
parents:
28732
diff
changeset
|
12 peer, |
33766
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
13 util, |
28800
544908ae36ce
test-batching: stop direct symbol import of mercurial modules
Yuya Nishihara <yuya@tcha.org>
parents:
28732
diff
changeset
|
14 wireproto, |
28731
f8872b507cd3
py3: use absolute_import in test-batching.py
Robert Stanca <robert.stanca7@gmail.com>
parents:
25912
diff
changeset
|
15 ) |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
16 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
17 # equivalent of repo.repository |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
18 class thing(object): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
19 def hello(self): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
20 return "Ready." |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
21 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
22 # equivalent of localrepo.localrepository |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
23 class localthing(thing): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
24 def foo(self, one, two=None): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
25 if one: |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
26 return "%s and %s" % (one, two,) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
27 return "Nope" |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
28 def bar(self, b, a): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
29 return "%s und %s" % (b, a,) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
30 def greet(self, name=None): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
31 return "Hello, %s" % name |
33766
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
32 def batchiter(self): |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
33 '''Support for local batching.''' |
33766
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
34 return peer.localiterbatcher(self) |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
35 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
36 # usage of "thing" interface |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
37 def use(it): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
38 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
39 # Direct call to base method shared between client and server. |
28732
e2b118592c63
py3: use print_function in test-batching.py
Robert Stanca <robert.stanca7@gmail.com>
parents:
28731
diff
changeset
|
40 print(it.hello()) |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
41 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
42 # Direct calls to proxied methods. They cause individual roundtrips. |
28732
e2b118592c63
py3: use print_function in test-batching.py
Robert Stanca <robert.stanca7@gmail.com>
parents:
28731
diff
changeset
|
43 print(it.foo("Un", two="Deux")) |
e2b118592c63
py3: use print_function in test-batching.py
Robert Stanca <robert.stanca7@gmail.com>
parents:
28731
diff
changeset
|
44 print(it.bar("Eins", "Zwei")) |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
45 |
33766
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
46 # Batched call to a couple of proxied methods. |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
47 batch = it.batchiter() |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
48 # The calls return futures to eventually hold results. |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
49 foo = batch.foo(one="One", two="Two") |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
50 bar = batch.bar("Eins", "Zwei") |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
51 bar2 = batch.bar(b="Uno", a="Due") |
33766
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
52 |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
53 # Future shouldn't be set until we submit(). |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
54 assert isinstance(foo, peer.future) |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
55 assert not util.safehasattr(foo, 'value') |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
56 assert not util.safehasattr(bar, 'value') |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
57 batch.submit() |
33766
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
58 # Call results() to obtain results as a generator. |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
59 results = batch.results() |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
60 |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
61 # Future results shouldn't be set until we consume a value. |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
62 assert not util.safehasattr(foo, 'value') |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
63 foovalue = next(results) |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
64 assert util.safehasattr(foo, 'value') |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
65 assert foovalue == foo.value |
28732
e2b118592c63
py3: use print_function in test-batching.py
Robert Stanca <robert.stanca7@gmail.com>
parents:
28731
diff
changeset
|
66 print(foo.value) |
33766
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
67 next(results) |
28732
e2b118592c63
py3: use print_function in test-batching.py
Robert Stanca <robert.stanca7@gmail.com>
parents:
28731
diff
changeset
|
68 print(bar.value) |
33766
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
69 next(results) |
28732
e2b118592c63
py3: use print_function in test-batching.py
Robert Stanca <robert.stanca7@gmail.com>
parents:
28731
diff
changeset
|
70 print(bar2.value) |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
71 |
33766
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
72 # We should be at the end of the results generator. |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
73 try: |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
74 next(results) |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
75 except StopIteration: |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
76 print('proper end of results generator') |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
77 else: |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
78 print('extra emitted element!') |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
79 |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
80 # Attempting to call a non-batchable method inside a batch fails. |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
81 batch = it.batchiter() |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
82 try: |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
83 batch.greet(name='John Smith') |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
84 except error.ProgrammingError as e: |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
85 print(e) |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
86 |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
87 # Attempting to call a local method inside a batch fails. |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
88 batch = it.batchiter() |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
89 try: |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
90 batch.hello() |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
91 except error.ProgrammingError as e: |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
92 print(e) |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
93 |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
94 # local usage |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
95 mylocal = localthing() |
28732
e2b118592c63
py3: use print_function in test-batching.py
Robert Stanca <robert.stanca7@gmail.com>
parents:
28731
diff
changeset
|
96 print() |
e2b118592c63
py3: use print_function in test-batching.py
Robert Stanca <robert.stanca7@gmail.com>
parents:
28731
diff
changeset
|
97 print("== Local") |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
98 use(mylocal) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
99 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
100 # demo remoting; mimicks what wireproto and HTTP/SSH do |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
101 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
102 # shared |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
103 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
104 def escapearg(plain): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
105 return (plain |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
106 .replace(':', '::') |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
107 .replace(',', ':,') |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
108 .replace(';', ':;') |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
109 .replace('=', ':=')) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
110 def unescapearg(escaped): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
111 return (escaped |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
112 .replace(':=', '=') |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
113 .replace(':;', ';') |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
114 .replace(':,', ',') |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
115 .replace('::', ':')) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
116 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
117 # server side |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
118 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
119 # equivalent of wireproto's global functions |
14764
a7d5816087a9
classes: fix class style problems found by b071cd58af50
Thomas Arendsen Hein <thomas@intevation.de>
parents:
14621
diff
changeset
|
120 class server(object): |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
121 def __init__(self, local): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
122 self.local = local |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
123 def _call(self, name, args): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
124 args = dict(arg.split('=', 1) for arg in args) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
125 return getattr(self, name)(**args) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
126 def perform(self, req): |
28732
e2b118592c63
py3: use print_function in test-batching.py
Robert Stanca <robert.stanca7@gmail.com>
parents:
28731
diff
changeset
|
127 print("REQ:", req) |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
128 name, args = req.split('?', 1) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
129 args = args.split('&') |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
130 vals = dict(arg.split('=', 1) for arg in args) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
131 res = getattr(self, name)(**vals) |
28732
e2b118592c63
py3: use print_function in test-batching.py
Robert Stanca <robert.stanca7@gmail.com>
parents:
28731
diff
changeset
|
132 print(" ->", res) |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
133 return res |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
134 def batch(self, cmds): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
135 res = [] |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
136 for pair in cmds.split(';'): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
137 name, args = pair.split(':', 1) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
138 vals = {} |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
139 for a in args.split(','): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
140 if a: |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
141 n, v = a.split('=') |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
142 vals[n] = unescapearg(v) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
143 res.append(escapearg(getattr(self, name)(**vals))) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
144 return ';'.join(res) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
145 def foo(self, one, two): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
146 return mangle(self.local.foo(unmangle(one), unmangle(two))) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
147 def bar(self, b, a): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
148 return mangle(self.local.bar(unmangle(b), unmangle(a))) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
149 def greet(self, name): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
150 return mangle(self.local.greet(unmangle(name))) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
151 myserver = server(mylocal) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
152 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
153 # local side |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
154 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
155 # equivalent of wireproto.encode/decodelist, that is, type-specific marshalling |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
156 # here we just transform the strings a bit to check we're properly en-/decoding |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
157 def mangle(s): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
158 return ''.join(chr(ord(c) + 1) for c in s) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
159 def unmangle(s): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
160 return ''.join(chr(ord(c) - 1) for c in s) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
161 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
162 # equivalent of wireproto.wirerepository and something like http's wire format |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
163 class remotething(thing): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
164 def __init__(self, server): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
165 self.server = server |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
166 def _submitone(self, name, args): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
167 req = name + '?' + '&'.join(['%s=%s' % (n, v) for n, v in args]) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
168 return self.server.perform(req) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
169 def _submitbatch(self, cmds): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
170 req = [] |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
171 for name, args in cmds: |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
172 args = ','.join(n + '=' + escapearg(v) for n, v in args) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
173 req.append(name + ':' + args) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
174 req = ';'.join(req) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
175 res = self._submitone('batch', [('cmds', req,)]) |
33766
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
176 for r in res.split(';'): |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
177 yield r |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
178 |
33766
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
179 def batchiter(self): |
4c706037adef
wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33765
diff
changeset
|
180 return wireproto.remoteiterbatcher(self) |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
181 |
28800
544908ae36ce
test-batching: stop direct symbol import of mercurial modules
Yuya Nishihara <yuya@tcha.org>
parents:
28732
diff
changeset
|
182 @peer.batchable |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
183 def foo(self, one, two=None): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
184 encargs = [('one', mangle(one),), ('two', mangle(two),)] |
28800
544908ae36ce
test-batching: stop direct symbol import of mercurial modules
Yuya Nishihara <yuya@tcha.org>
parents:
28732
diff
changeset
|
185 encresref = peer.future() |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
186 yield encargs, encresref |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
187 yield unmangle(encresref.value) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
188 |
28800
544908ae36ce
test-batching: stop direct symbol import of mercurial modules
Yuya Nishihara <yuya@tcha.org>
parents:
28732
diff
changeset
|
189 @peer.batchable |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
190 def bar(self, b, a): |
28800
544908ae36ce
test-batching: stop direct symbol import of mercurial modules
Yuya Nishihara <yuya@tcha.org>
parents:
28732
diff
changeset
|
191 encresref = peer.future() |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
192 yield [('b', mangle(b),), ('a', mangle(a),)], encresref |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
193 yield unmangle(encresref.value) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
194 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
195 # greet is coded directly. It therefore does not support batching. If it |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
196 # does appear in a batch, the batch is split around greet, and the call to |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
197 # greet is done in its own roundtrip. |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
198 def greet(self, name=None): |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
199 return unmangle(self._submitone('greet', [('name', mangle(name),)])) |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
200 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
201 # demo remote usage |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
202 |
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
203 myproxy = remotething(myserver) |
28732
e2b118592c63
py3: use print_function in test-batching.py
Robert Stanca <robert.stanca7@gmail.com>
parents:
28731
diff
changeset
|
204 print() |
e2b118592c63
py3: use print_function in test-batching.py
Robert Stanca <robert.stanca7@gmail.com>
parents:
28731
diff
changeset
|
205 print("== Remote") |
14621
84094c0d2724
wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff
changeset
|
206 use(myproxy) |