##// END OF EJS Templates
httppeer: expose API descriptor on httpv2peer...
httppeer: expose API descriptor on httpv2peer The API descriptor in wireprotov2 is much more expressive than space-delimited tokens and it will be difficult to define methods to query it in all of the ways we'll want to query it. So let's just declare defeat and expose the API descriptor on the peer instance. As part of this, we define a new interface for version 2 peers, fulfilling a TODO in the process. Differential Revision: https://phab.mercurial-scm.org/D4974

File last commit:

r37651:33a6eee0 default
r40207:dac438b7 default
Show More
test-batching.py
180 lines | 5.2 KiB | text/x-python | PythonLexer
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 # test-batching.py - tests for transparent command batching
#
# Copyright 2011 Peter Arrenbrecht <peter@arrenbrecht.ch>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Robert Stanca
py3: use print_function in test-batching.py
r28732 from __future__ import absolute_import, print_function
Yuya Nishihara
test-batching: stop direct symbol import of mercurial modules...
r28800
Gregory Szorc
wireproto: remove iterbatch() from peer interface (API)...
r37651 import contextlib
Yuya Nishihara
test-batching: stop direct symbol import of mercurial modules...
r28800 from mercurial import (
Gregory Szorc
peer: scatter module to the wind (API)...
r37633 localrepo,
Gregory Szorc
wireproto: move version 1 peer functionality to standalone module (API)...
r37632 wireprotov1peer,
Gregory Szorc
peer: scatter module to the wind (API)...
r37633
Robert Stanca
py3: use absolute_import in test-batching.py
r28731 )
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
# equivalent of repo.repository
class thing(object):
def hello(self):
return "Ready."
# equivalent of localrepo.localrepository
class localthing(thing):
def foo(self, one, two=None):
if one:
return "%s and %s" % (one, two,)
return "Nope"
def bar(self, b, a):
return "%s und %s" % (b, a,)
def greet(self, name=None):
return "Hello, %s" % name
Gregory Szorc
wireproto: remove iterbatch() from peer interface (API)...
r37651
@contextlib.contextmanager
def commandexecutor(self):
e = localrepo.localcommandexecutor(self)
try:
yield e
finally:
e.close()
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
# usage of "thing" interface
def use(it):
# Direct call to base method shared between client and server.
Robert Stanca
py3: use print_function in test-batching.py
r28732 print(it.hello())
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
# Direct calls to proxied methods. They cause individual roundtrips.
Robert Stanca
py3: use print_function in test-batching.py
r28732 print(it.foo("Un", two="Deux"))
print(it.bar("Eins", "Zwei"))
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
Gregory Szorc
wireproto: overhaul iterating batcher code (API)...
r33761 # Batched call to a couple of proxied methods.
Gregory Szorc
wireproto: remove iterbatch() from peer interface (API)...
r37651 with it.commandexecutor() as e:
ffoo = e.callcommand('foo', {'one': 'One', 'two': 'Two'})
fbar = e.callcommand('bar', {'b': 'Eins', 'a': 'Zwei'})
fbar2 = e.callcommand('bar', {'b': 'Uno', 'a': 'Due'})
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
Gregory Szorc
wireproto: remove iterbatch() from peer interface (API)...
r37651 print(ffoo.result())
print(fbar.result())
print(fbar2.result())
Gregory Szorc
wireproto: overhaul iterating batcher code (API)...
r33761
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 # local usage
mylocal = localthing()
Robert Stanca
py3: use print_function in test-batching.py
r28732 print()
print("== Local")
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 use(mylocal)
# demo remoting; mimicks what wireproto and HTTP/SSH do
# shared
def escapearg(plain):
return (plain
.replace(':', '::')
.replace(',', ':,')
.replace(';', ':;')
.replace('=', ':='))
def unescapearg(escaped):
return (escaped
.replace(':=', '=')
.replace(':;', ';')
.replace(':,', ',')
.replace('::', ':'))
# server side
# equivalent of wireproto's global functions
Thomas Arendsen Hein
classes: fix class style problems found by b071cd58af50...
r14764 class server(object):
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 def __init__(self, local):
self.local = local
def _call(self, name, args):
args = dict(arg.split('=', 1) for arg in args)
return getattr(self, name)(**args)
def perform(self, req):
Robert Stanca
py3: use print_function in test-batching.py
r28732 print("REQ:", req)
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 name, args = req.split('?', 1)
args = args.split('&')
vals = dict(arg.split('=', 1) for arg in args)
res = getattr(self, name)(**vals)
Robert Stanca
py3: use print_function in test-batching.py
r28732 print(" ->", res)
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 return res
def batch(self, cmds):
res = []
for pair in cmds.split(';'):
name, args = pair.split(':', 1)
vals = {}
for a in args.split(','):
if a:
n, v = a.split('=')
vals[n] = unescapearg(v)
res.append(escapearg(getattr(self, name)(**vals)))
return ';'.join(res)
def foo(self, one, two):
return mangle(self.local.foo(unmangle(one), unmangle(two)))
def bar(self, b, a):
return mangle(self.local.bar(unmangle(b), unmangle(a)))
def greet(self, name):
return mangle(self.local.greet(unmangle(name)))
myserver = server(mylocal)
# local side
# equivalent of wireproto.encode/decodelist, that is, type-specific marshalling
# here we just transform the strings a bit to check we're properly en-/decoding
def mangle(s):
return ''.join(chr(ord(c) + 1) for c in s)
def unmangle(s):
return ''.join(chr(ord(c) - 1) for c in s)
# equivalent of wireproto.wirerepository and something like http's wire format
class remotething(thing):
def __init__(self, server):
self.server = server
def _submitone(self, name, args):
req = name + '?' + '&'.join(['%s=%s' % (n, v) for n, v in args])
return self.server.perform(req)
def _submitbatch(self, cmds):
req = []
for name, args in cmds:
args = ','.join(n + '=' + escapearg(v) for n, v in args)
req.append(name + ':' + args)
req = ';'.join(req)
res = self._submitone('batch', [('cmds', req,)])
Gregory Szorc
wireproto: overhaul iterating batcher code (API)...
r33761 for r in res.split(';'):
yield r
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
Gregory Szorc
wireproto: remove iterbatch() from peer interface (API)...
r37651 @contextlib.contextmanager
def commandexecutor(self):
e = wireprotov1peer.peerexecutor(self)
try:
yield e
finally:
e.close()
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
Gregory Szorc
peer: scatter module to the wind (API)...
r37633 @wireprotov1peer.batchable
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 def foo(self, one, two=None):
encargs = [('one', mangle(one),), ('two', mangle(two),)]
Gregory Szorc
peer: scatter module to the wind (API)...
r37633 encresref = wireprotov1peer.future()
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 yield encargs, encresref
yield unmangle(encresref.value)
Gregory Szorc
peer: scatter module to the wind (API)...
r37633 @wireprotov1peer.batchable
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 def bar(self, b, a):
Gregory Szorc
peer: scatter module to the wind (API)...
r37633 encresref = wireprotov1peer.future()
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 yield [('b', mangle(b),), ('a', mangle(a),)], encresref
yield unmangle(encresref.value)
# greet is coded directly. It therefore does not support batching. If it
# does appear in a batch, the batch is split around greet, and the call to
# greet is done in its own roundtrip.
def greet(self, name=None):
return unmangle(self._submitone('greet', [('name', mangle(name),)]))
# demo remote usage
myproxy = remotething(myserver)
Robert Stanca
py3: use print_function in test-batching.py
r28732 print()
print("== Remote")
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 use(myproxy)