tests/test-batching.py
author Augie Fackler <augie@google.com>
Tue, 20 Jan 2015 13:38:07 -0500
changeset 24018 26d6a6a78c1d
parent 14764 a7d5816087a9
child 25912 cbbdd085c991
permissions -rw-r--r--
obsolete: use parsers.fm1readmarker if it exists for a ~38% perf win This moves perfloadmarkers on my linux workstation (63494 markers from mpm, crew, and myself) performance from ! wall 0.357657 comb 0.360000 user 0.350000 sys 0.010000 (best of 28) to ! wall 0.222345 comb 0.220000 user 0.210000 sys 0.010000 (best of 41) which is a pretty good improvement. On my BSD machine, which is ancient and slow, before: ! wall 3.584964 comb 3.578125 user 3.539062 sys 0.039062 (best of 3) after: ! wall 2.267974 comb 2.265625 user 2.195312 sys 0.070312 (best of 5) I feel like we could do better by moving the whole generator function into C, but I didn't want to tackle that right away.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
     8
from mercurial.wireproto import localbatch, remotebatch, batchable, future
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
     9
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    10
# equivalent of repo.repository
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    11
class thing(object):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    12
    def hello(self):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    13
        return "Ready."
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    14
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    15
# equivalent of localrepo.localrepository
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    16
class localthing(thing):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    17
    def foo(self, one, two=None):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    18
        if one:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    19
            return "%s and %s" % (one, two,)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    20
        return "Nope"
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    21
    def bar(self, b, a):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    22
        return "%s und %s" % (b, a,)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    23
    def greet(self, name=None):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    24
        return "Hello, %s" % name
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    25
    def batch(self):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    26
        '''Support for local batching.'''
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    27
        return localbatch(self)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    28
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    29
# usage of "thing" interface
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    30
def use(it):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    31
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    32
    # Direct call to base method shared between client and server.
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    33
    print it.hello()
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    34
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    35
    # Direct calls to proxied methods. They cause individual roundtrips.
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    36
    print it.foo("Un", two="Deux")
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    37
    print it.bar("Eins", "Zwei")
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
    # Batched call to a couple of (possibly proxied) methods.
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    40
    batch = it.batch()
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    41
    # The calls return futures to eventually hold results.
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    42
    foo = batch.foo(one="One", two="Two")
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    43
    foo2 = batch.foo(None)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    44
    bar = batch.bar("Eins", "Zwei")
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    45
    # We can call non-batchable proxy methods, but the break the current batch
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    46
    # request and cause additional roundtrips.
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    47
    greet = batch.greet(name="John Smith")
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    48
    # We can also add local methods into the mix, but they break the batch too.
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    49
    hello = batch.hello()
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    50
    bar2 = batch.bar(b="Uno", a="Due")
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    51
    # Only now are all the calls executed in sequence, with as few roundtrips
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    52
    # as possible.
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    53
    batch.submit()
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    54
    # After the call to submit, the futures actually contain values.
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    55
    print foo.value
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    56
    print foo2.value
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    57
    print bar.value
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    58
    print greet.value
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    59
    print hello.value
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    60
    print bar2.value
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    61
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    62
# local usage
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    63
mylocal = localthing()
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    64
print
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    65
print "== Local"
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    66
use(mylocal)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    67
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    68
# 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
    69
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    70
# shared
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    71
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    72
def escapearg(plain):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    73
    return (plain
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    74
            .replace(':', '::')
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    75
            .replace(',', ':,')
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    76
            .replace(';', ':;')
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    77
            .replace('=', ':='))
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    78
def unescapearg(escaped):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    79
    return (escaped
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    80
            .replace(':=', '=')
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    81
            .replace(':;', ';')
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    82
            .replace(':,', ',')
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    83
            .replace('::', ':'))
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    84
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    85
# server side
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    86
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    87
# 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
    88
class server(object):
14621
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    89
    def __init__(self, local):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    90
        self.local = local
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    91
    def _call(self, name, args):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    92
        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
    93
        return getattr(self, name)(**args)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    94
    def perform(self, req):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    95
        print "REQ:", req
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    96
        name, args = req.split('?', 1)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    97
        args = args.split('&')
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
    98
        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
    99
        res = getattr(self, name)(**vals)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   100
        print "  ->", res
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   101
        return res
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   102
    def batch(self, cmds):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   103
        res = []
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   104
        for pair in cmds.split(';'):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   105
            name, args = pair.split(':', 1)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   106
            vals = {}
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   107
            for a in args.split(','):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   108
                if a:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   109
                    n, v = a.split('=')
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   110
                    vals[n] = unescapearg(v)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   111
            res.append(escapearg(getattr(self, name)(**vals)))
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   112
        return ';'.join(res)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   113
    def foo(self, one, two):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   114
        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
   115
    def bar(self, b, a):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   116
        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
   117
    def greet(self, name):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   118
        return mangle(self.local.greet(unmangle(name)))
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   119
myserver = server(mylocal)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   120
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   121
# local side
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   122
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   123
# 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
   124
# 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
   125
def mangle(s):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   126
    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
   127
def unmangle(s):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   128
    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
   129
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   130
# 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
   131
class remotething(thing):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   132
    def __init__(self, server):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   133
        self.server = server
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   134
    def _submitone(self, name, args):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   135
        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
   136
        return self.server.perform(req)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   137
    def _submitbatch(self, cmds):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   138
        req = []
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   139
        for name, args in cmds:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   140
            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
   141
            req.append(name + ':' + args)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   142
        req = ';'.join(req)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   143
        res = self._submitone('batch', [('cmds', req,)])
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   144
        return res.split(';')
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   145
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   146
    def batch(self):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   147
        return remotebatch(self)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   148
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   149
    @batchable
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   150
    def foo(self, one, two=None):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   151
        if not one:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   152
            yield "Nope", None
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   153
        encargs = [('one', mangle(one),), ('two', mangle(two),)]
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   154
        encresref = future()
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   155
        yield encargs, encresref
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   156
        yield unmangle(encresref.value)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   157
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   158
    @batchable
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   159
    def bar(self, b, a):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   160
        encresref = future()
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   161
        yield [('b', mangle(b),), ('a', mangle(a),)], encresref
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   162
        yield unmangle(encresref.value)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   163
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   164
    # 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
   165
    # 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
   166
    # greet is done in its own roundtrip.
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   167
    def greet(self, name=None):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   168
        return unmangle(self._submitone('greet', [('name', mangle(name),)]))
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   169
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   170
# demo remote usage
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   171
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   172
myproxy = remotething(myserver)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   173
print
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   174
print "== Remote"
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
diff changeset
   175
use(myproxy)