##// END OF EJS Templates
wireproto: add batching support to wirerepository...
Peter Arrenbrecht -
r14622:bd88561a default
parent child Browse files
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]
@@ -0,0 +1,2 b''
1 Hello, Foobar
2 ['Hello, Fo, =;o', 'Hello, Bar']
@@ -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