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 | def encodelist(l, sep=' '): |
|
126 | def encodelist(l, sep=' '): | |
127 | return sep.join(map(hex, l)) |
|
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 | # client side |
|
145 | # client side | |
130 |
|
146 | |||
|
147 | def todict(**args): | |||
|
148 | return args | |||
|
149 | ||||
131 | class wirerepository(repo.repository): |
|
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 | def lookup(self, key): |
|
164 | def lookup(self, key): | |
133 | self.requirecap('lookup', _('look up remote revision')) |
|
165 | self.requirecap('lookup', _('look up remote revision')) | |
134 | d = self._call("lookup", key=encoding.fromlocal(key)) |
|
166 | d = self._call("lookup", key=encoding.fromlocal(key)) | |
@@ -302,6 +334,34 b' def options(cmd, keys, others):' | |||||
302 | % (cmd, ",".join(others))) |
|
334 | % (cmd, ",".join(others))) | |
303 | return opts |
|
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 | def between(repo, proto, pairs): |
|
365 | def between(repo, proto, pairs): | |
306 | pairs = [decodelist(p, '-') for p in pairs.split(" ")] |
|
366 | pairs = [decodelist(p, '-') for p in pairs.split(" ")] | |
307 | r = [] |
|
367 | r = [] | |
@@ -327,7 +387,7 b' def branches(repo, proto, nodes):' | |||||
327 |
|
387 | |||
328 | def capabilities(repo, proto): |
|
388 | def capabilities(repo, proto): | |
329 | caps = ('lookup changegroupsubset branchmap pushkey known getbundle ' |
|
389 | caps = ('lookup changegroupsubset branchmap pushkey known getbundle ' | |
330 | 'unbundlehash').split() |
|
390 | 'unbundlehash batch').split() | |
331 | if _allowstream(repo.ui): |
|
391 | if _allowstream(repo.ui): | |
332 | requiredformats = repo.requirements & repo.supportedformats |
|
392 | requiredformats = repo.requirements & repo.supportedformats | |
333 | # if our local revlogs are just revlogv1, add 'stream' cap |
|
393 | # if our local revlogs are just revlogv1, add 'stream' cap | |
@@ -506,6 +566,7 b' def unbundle(repo, proto, heads):' | |||||
506 | os.unlink(tempname) |
|
566 | os.unlink(tempname) | |
507 |
|
567 | |||
508 | commands = { |
|
568 | commands = { | |
|
569 | 'batch': (batch, 'cmds *'), | |||
509 | 'between': (between, 'pairs'), |
|
570 | 'between': (between, 'pairs'), | |
510 | 'branchmap': (branchmap, ''), |
|
571 | 'branchmap': (branchmap, ''), | |
511 | 'branches': (branches, 'nodes'), |
|
572 | 'branches': (branches, 'nodes'), |
@@ -981,7 +981,7 b' capabilities' | |||||
981 | $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities'; echo |
|
981 | $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities'; echo | |
982 | 200 Script output follows |
|
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 | heads |
|
986 | heads | |
987 |
|
987 |
General Comments 0
You need to be logged in to leave comments.
Login now