Show More
@@ -0,0 +1,45 b'' | |||
|
1 | from mercurial import wireproto | |
|
2 | ||
|
3 | class proto(): | |
|
4 | def __init__(self, args): | |
|
5 | self.args = args | |
|
6 | def getargs(self, spec): | |
|
7 | args = self.args | |
|
8 | args.setdefault('*', {}) | |
|
9 | names = spec.split() | |
|
10 | return [args[n] for n in names] | |
|
11 | ||
|
12 | class clientrepo(wireproto.wirerepository): | |
|
13 | def __init__(self, serverrepo): | |
|
14 | self.serverrepo = serverrepo | |
|
15 | def _call(self, cmd, **args): | |
|
16 | return wireproto.dispatch(self.serverrepo, proto(args), cmd) | |
|
17 | ||
|
18 | @wireproto.batchable | |
|
19 | def greet(self, name): | |
|
20 | f = wireproto.future() | |
|
21 | yield wireproto.todict(name=mangle(name)), f | |
|
22 | yield unmangle(f.value) | |
|
23 | ||
|
24 | class serverrepo(): | |
|
25 | def greet(self, name): | |
|
26 | return "Hello, " + name | |
|
27 | ||
|
28 | def mangle(s): | |
|
29 | return ''.join(chr(ord(c) + 1) for c in s) | |
|
30 | def unmangle(s): | |
|
31 | return ''.join(chr(ord(c) - 1) for c in s) | |
|
32 | ||
|
33 | def greet(repo, proto, name): | |
|
34 | return mangle(repo.greet(unmangle(name))) | |
|
35 | ||
|
36 | wireproto.commands['greet'] = (greet, 'name',) | |
|
37 | ||
|
38 | srv = serverrepo() | |
|
39 | clt = clientrepo(srv) | |
|
40 | ||
|
41 | print clt.greet("Foobar") | |
|
42 | b = clt.batch() | |
|
43 | fs = [b.greet(s) for s in ["Fo, =;o", "Bar"]] | |
|
44 | b.submit() | |
|
45 | print [f.value for f in fs] |
@@ -126,9 +126,41 b" def decodelist(l, sep=' '):" | |||
|
126 | 126 | def encodelist(l, sep=' '): |
|
127 | 127 | return sep.join(map(hex, l)) |
|
128 | 128 | |
|
129 | # batched call argument encoding | |
|
130 | ||
|
131 | def escapearg(plain): | |
|
132 | return (plain | |
|
133 | .replace(':', '::') | |
|
134 | .replace(',', ':,') | |
|
135 | .replace(';', ':;') | |
|
136 | .replace('=', ':=')) | |
|
137 | ||
|
138 | def unescapearg(escaped): | |
|
139 | return (escaped | |
|
140 | .replace(':=', '=') | |
|
141 | .replace(':;', ';') | |
|
142 | .replace(':,', ',') | |
|
143 | .replace('::', ':')) | |
|
144 | ||
|
129 | 145 | # client side |
|
130 | 146 | |
|
147 | def todict(**args): | |
|
148 | return args | |
|
149 | ||
|
131 | 150 | class wirerepository(repo.repository): |
|
151 | ||
|
152 | def batch(self): | |
|
153 | return remotebatch(self) | |
|
154 | def _submitbatch(self, req): | |
|
155 | cmds = [] | |
|
156 | for op, argsdict in req: | |
|
157 | args = ','.join('%s=%s' % p for p in argsdict.iteritems()) | |
|
158 | cmds.append('%s %s' % (op, args)) | |
|
159 | rsp = self._call("batch", cmds=';'.join(cmds)) | |
|
160 | return rsp.split(';') | |
|
161 | def _submitone(self, op, args): | |
|
162 | return self._call(op, **args) | |
|
163 | ||
|
132 | 164 | def lookup(self, key): |
|
133 | 165 | self.requirecap('lookup', _('look up remote revision')) |
|
134 | 166 | d = self._call("lookup", key=encoding.fromlocal(key)) |
@@ -302,6 +334,34 b' def options(cmd, keys, others):' | |||
|
302 | 334 | % (cmd, ",".join(others))) |
|
303 | 335 | return opts |
|
304 | 336 | |
|
337 | def batch(repo, proto, cmds, others): | |
|
338 | res = [] | |
|
339 | for pair in cmds.split(';'): | |
|
340 | op, args = pair.split(' ', 1) | |
|
341 | vals = {} | |
|
342 | for a in args.split(','): | |
|
343 | if a: | |
|
344 | n, v = a.split('=') | |
|
345 | vals[n] = unescapearg(v) | |
|
346 | func, spec = commands[op] | |
|
347 | if spec: | |
|
348 | keys = spec.split() | |
|
349 | data = {} | |
|
350 | for k in keys: | |
|
351 | if k == '*': | |
|
352 | star = {} | |
|
353 | for key in vals.keys(): | |
|
354 | if key not in keys: | |
|
355 | star[key] = vals[key] | |
|
356 | data['*'] = star | |
|
357 | else: | |
|
358 | data[k] = vals[k] | |
|
359 | result = func(repo, proto, *[data[k] for k in keys]) | |
|
360 | else: | |
|
361 | result = func(repo, proto) | |
|
362 | res.append(escapearg(result)) | |
|
363 | return ';'.join(res) | |
|
364 | ||
|
305 | 365 | def between(repo, proto, pairs): |
|
306 | 366 | pairs = [decodelist(p, '-') for p in pairs.split(" ")] |
|
307 | 367 | r = [] |
@@ -327,7 +387,7 b' def branches(repo, proto, nodes):' | |||
|
327 | 387 | |
|
328 | 388 | def capabilities(repo, proto): |
|
329 | 389 | caps = ('lookup changegroupsubset branchmap pushkey known getbundle ' |
|
330 | 'unbundlehash').split() | |
|
390 | 'unbundlehash batch').split() | |
|
331 | 391 | if _allowstream(repo.ui): |
|
332 | 392 | requiredformats = repo.requirements & repo.supportedformats |
|
333 | 393 | # if our local revlogs are just revlogv1, add 'stream' cap |
@@ -506,6 +566,7 b' def unbundle(repo, proto, heads):' | |||
|
506 | 566 | os.unlink(tempname) |
|
507 | 567 | |
|
508 | 568 | commands = { |
|
569 | 'batch': (batch, 'cmds *'), | |
|
509 | 570 | 'between': (between, 'pairs'), |
|
510 | 571 | 'branchmap': (branchmap, ''), |
|
511 | 572 | 'branches': (branches, 'nodes'), |
@@ -981,7 +981,7 b' capabilities' | |||
|
981 | 981 | $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities'; echo |
|
982 | 982 | 200 Script output follows |
|
983 | 983 | |
|
984 | lookup changegroupsubset branchmap pushkey known getbundle unbundlehash unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 | |
|
984 | lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 | |
|
985 | 985 | |
|
986 | 986 | heads |
|
987 | 987 |
General Comments 0
You need to be logged in to leave comments.
Login now