contrib/hgclient.py
author Georges Racinet <georges.racinet@octobus.net>
Wed, 20 Feb 2019 09:04:54 +0100
changeset 42745 4d20b1fe8a72
parent 40984 6a372f943e49
child 43076 2372284d9457
permissions -rw-r--r--
rust-discovery: using from Python code As previously done in other topics, the Rust version is used if it's been built. The version fully in Rust of the partialdiscovery class has the performance advantage over the Python version (actually using the Rust MissingAncestor) if the undecided set is big enough. Otherwise no sampling occurs, and the discovery is reasonably fast anyway. Note: it's hard to predict the size of the initial undecided set, it can depend on the kind of topological changes between the local and remote graphs. The point of the Rust version is to make the bad cases acceptable. More specifically, the performance advantages are: - faster sampling, especially takefullsample() - much faster addmissings() in almost all cases (see commit message in grandparent of the present changeset) - no conversion cost of the undecided set at the interface between Rust and Python == Measurements with big undecided sets For an extreme example, discovery between mozilla-try and mozilla-unified (over one million undecided revisions, same case as in dbd0fcca6dfc), we get roughly a x2.5/x3 better performance: Growing sample size (5% starting with 200): time goes down from 210 to 72 seconds. Constant sample size of 200: time down from 1853 to 659 seconds. With a sample size computed from number of roots and heads of the undecided set (`respectsize` is `False`), here are perfdiscovery results: Before ! wall 9.358729 comb 9.360000 user 9.310000 sys 0.050000 (median of 50) After ! wall 3.793819 comb 3.790000 user 3.750000 sys 0.040000 (median of 50) In that later case, the sample sizes are routinely in the hundreds of thousands of revisions. While still faster, the Rust iteration in addmissings has less of an advantage than with smaller sample sizes, but one sees addcommons becoming faster, probably a consequence of not having to copy big sets back and forth. This example is not a goal in itself, but it showcases several different areas in which the process can become slow, due to different factors, and how this full Rust version can help. == Measurements with small undecided sets In cases the undecided set is small enough than no sampling occurs, the Rust version has a disadvantage at init if `targetheads` is really big (some time is lost in the translation to Rust data structures), and that is compensated by the faster `addmissings()`. On a private repository with over one million commits, we still get a minor improvement, of 6.8%: Before ! wall 0.593585 comb 0.590000 user 0.550000 sys 0.040000 (median of 50) After ! wall 0.553035 comb 0.550000 user 0.520000 sys 0.030000 (median of 50) What's interesting in that case is the first addinfo() at 180ms for Rust and 233ms for Python+C, mostly due to add_missings and the children cache computation being done in less than 0.2ms on the Rust side vs over 40ms on the Python side. The worst case we have on hand is with mozilla-try, prepared with discovery-helper.sh for 10 heads and depth 10, time goes up 2.2% on the median. In this case `targetheads` is really huge with 165842 server heads. Before ! wall 0.823884 comb 0.810000 user 0.790000 sys 0.020000 (median of 50) After ! wall 0.842607 comb 0.840000 user 0.800000 sys 0.040000 (median of 50) If that would be considered a problem, more adjustments can be made, which are prematurate at this stage: cooking special variants of methods of the inner MissingAncestors object, retrieving local heads directly from Rust to avoid the cost of conversion. Effort would probably be better spent at this point improving the surroundings if needed. Here's another data point with a smaller repository, pypy, where performance is almost identical Before ! wall 0.015121 comb 0.030000 user 0.020000 sys 0.010000 (median of 186) After ! wall 0.015009 comb 0.010000 user 0.010000 sys 0.000000 (median of 184) Differential Revision: https://phab.mercurial-scm.org/D6430
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     1
# A minimal client for Mercurial's command server
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     2
28355
897a4bbd578b hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 22993
diff changeset
     3
from __future__ import absolute_import, print_function
40317
6958eb9bdcd6 py3: rewrite StringIO fallback for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 40316
diff changeset
     4
6958eb9bdcd6 py3: rewrite StringIO fallback for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 40316
diff changeset
     5
import io
28355
897a4bbd578b hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 22993
diff changeset
     6
import os
40316
09540a5f0a15 py3: reinvent print() function for contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40315
diff changeset
     7
import re
28355
897a4bbd578b hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 22993
diff changeset
     8
import signal
897a4bbd578b hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 22993
diff changeset
     9
import socket
897a4bbd578b hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 22993
diff changeset
    10
import struct
897a4bbd578b hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 22993
diff changeset
    11
import subprocess
897a4bbd578b hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 22993
diff changeset
    12
import sys
897a4bbd578b hgclient: use absolute_import and print_function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 22993
diff changeset
    13
import time
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    14
40315
431a831342d2 py3: work around unicode stdio streams in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40314
diff changeset
    15
if sys.version_info[0] >= 3:
431a831342d2 py3: work around unicode stdio streams in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40314
diff changeset
    16
    stdout = sys.stdout.buffer
431a831342d2 py3: work around unicode stdio streams in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40314
diff changeset
    17
    stderr = sys.stderr.buffer
40317
6958eb9bdcd6 py3: rewrite StringIO fallback for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 40316
diff changeset
    18
    stringio = io.BytesIO
40316
09540a5f0a15 py3: reinvent print() function for contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40315
diff changeset
    19
    def bprint(*args):
09540a5f0a15 py3: reinvent print() function for contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40315
diff changeset
    20
        # remove b'' as well for ease of test migration
09540a5f0a15 py3: reinvent print() function for contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40315
diff changeset
    21
        pargs = [re.sub(br'''\bb(['"])''', br'\1', b'%s' % a) for a in args]
09540a5f0a15 py3: reinvent print() function for contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40315
diff changeset
    22
        stdout.write(b' '.join(pargs) + b'\n')
40315
431a831342d2 py3: work around unicode stdio streams in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40314
diff changeset
    23
else:
40317
6958eb9bdcd6 py3: rewrite StringIO fallback for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 40316
diff changeset
    24
    import cStringIO
40315
431a831342d2 py3: work around unicode stdio streams in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40314
diff changeset
    25
    stdout = sys.stdout
431a831342d2 py3: work around unicode stdio streams in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40314
diff changeset
    26
    stderr = sys.stderr
40317
6958eb9bdcd6 py3: rewrite StringIO fallback for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 40316
diff changeset
    27
    stringio = cStringIO.StringIO
40316
09540a5f0a15 py3: reinvent print() function for contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40315
diff changeset
    28
    bprint = print
40315
431a831342d2 py3: work around unicode stdio streams in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40314
diff changeset
    29
40589
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40317
diff changeset
    30
def connectpipe(path=None, extraargs=()):
40314
73c2b9c9cd3c py3: convert string literals to bytes in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 28836
diff changeset
    31
    cmdline = [b'hg', b'serve', b'--cmdserver', b'pipe']
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    32
    if path:
40314
73c2b9c9cd3c py3: convert string literals to bytes in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 28836
diff changeset
    33
        cmdline += [b'-R', path]
40589
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40317
diff changeset
    34
    cmdline.extend(extraargs)
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    35
40984
6a372f943e49 py3: convert popen() command arguments in hgclient to str on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 40589
diff changeset
    36
    def tonative(cmdline):
6a372f943e49 py3: convert popen() command arguments in hgclient to str on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 40589
diff changeset
    37
        if os.name != r'nt':
6a372f943e49 py3: convert popen() command arguments in hgclient to str on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 40589
diff changeset
    38
            return cmdline
6a372f943e49 py3: convert popen() command arguments in hgclient to str on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 40589
diff changeset
    39
        return [arg.decode("utf-8") for arg in cmdline]
6a372f943e49 py3: convert popen() command arguments in hgclient to str on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 40589
diff changeset
    40
6a372f943e49 py3: convert popen() command arguments in hgclient to str on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 40589
diff changeset
    41
    server = subprocess.Popen(tonative(cmdline), stdin=subprocess.PIPE,
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    42
                              stdout=subprocess.PIPE)
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    43
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    44
    return server
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    45
22993
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    46
class unixconnection(object):
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    47
    def __init__(self, sockpath):
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    48
        self.sock = sock = socket.socket(socket.AF_UNIX)
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    49
        sock.connect(sockpath)
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    50
        self.stdin = sock.makefile('wb')
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    51
        self.stdout = sock.makefile('rb')
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    52
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    53
    def wait(self):
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    54
        self.stdin.close()
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    55
        self.stdout.close()
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    56
        self.sock.close()
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    57
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    58
class unixserver(object):
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    59
    def __init__(self, sockpath, logpath=None, repopath=None):
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    60
        self.sockpath = sockpath
40314
73c2b9c9cd3c py3: convert string literals to bytes in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 28836
diff changeset
    61
        cmdline = [b'hg', b'serve', b'--cmdserver', b'unix', b'-a', sockpath]
22993
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    62
        if repopath:
40314
73c2b9c9cd3c py3: convert string literals to bytes in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 28836
diff changeset
    63
            cmdline += [b'-R', repopath]
22993
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    64
        if logpath:
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    65
            stdout = open(logpath, 'a')
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    66
            stderr = subprocess.STDOUT
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    67
        else:
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    68
            stdout = stderr = None
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    69
        self.server = subprocess.Popen(cmdline, stdout=stdout, stderr=stderr)
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    70
        # wait for listen()
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    71
        while self.server.poll() is None:
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    72
            if os.path.exists(sockpath):
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    73
                break
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    74
            time.sleep(0.1)
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    75
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    76
    def connect(self):
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    77
        return unixconnection(self.sockpath)
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    78
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    79
    def shutdown(self):
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    80
        os.kill(self.server.pid, signal.SIGTERM)
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    81
        self.server.wait()
24c5fd2894f8 test-commandserver: add connector for unix domain socket server
Yuya Nishihara <yuya@tcha.org>
parents: 22992
diff changeset
    82
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    83
def writeblock(server, data):
40314
73c2b9c9cd3c py3: convert string literals to bytes in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 28836
diff changeset
    84
    server.stdin.write(struct.pack(b'>I', len(data)))
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    85
    server.stdin.write(data)
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    86
    server.stdin.flush()
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    87
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    88
def readchannel(server):
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    89
    data = server.stdout.read(5)
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    90
    if not data:
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    91
        raise EOFError
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    92
    channel, length = struct.unpack('>cI', data)
40314
73c2b9c9cd3c py3: convert string literals to bytes in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 28836
diff changeset
    93
    if channel in b'IL':
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    94
        return channel, length
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    95
    else:
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    96
        return channel, server.stdout.read(length)
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    97
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    98
def sep(text):
40314
73c2b9c9cd3c py3: convert string literals to bytes in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 28836
diff changeset
    99
    return text.replace(b'\\', b'/')
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   100
40315
431a831342d2 py3: work around unicode stdio streams in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40314
diff changeset
   101
def runcommand(server, args, output=stdout, error=stderr, input=None,
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   102
               outfilter=lambda x: x):
40316
09540a5f0a15 py3: reinvent print() function for contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40315
diff changeset
   103
    bprint(b'*** runcommand', b' '.join(args))
40315
431a831342d2 py3: work around unicode stdio streams in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40314
diff changeset
   104
    stdout.flush()
40314
73c2b9c9cd3c py3: convert string literals to bytes in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 28836
diff changeset
   105
    server.stdin.write(b'runcommand\n')
73c2b9c9cd3c py3: convert string literals to bytes in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 28836
diff changeset
   106
    writeblock(server, b'\0'.join(args))
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   107
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   108
    if not input:
28836
3f45488d70df test-commandserver: handle cStringIO.StringIO/io.StringIO divergence
timeless <timeless@mozdev.org>
parents: 28355
diff changeset
   109
        input = stringio()
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   110
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   111
    while True:
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   112
        ch, data = readchannel(server)
40314
73c2b9c9cd3c py3: convert string literals to bytes in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 28836
diff changeset
   113
        if ch == b'o':
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   114
            output.write(outfilter(data))
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   115
            output.flush()
40314
73c2b9c9cd3c py3: convert string literals to bytes in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 28836
diff changeset
   116
        elif ch == b'e':
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   117
            error.write(data)
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   118
            error.flush()
40314
73c2b9c9cd3c py3: convert string literals to bytes in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 28836
diff changeset
   119
        elif ch == b'I':
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   120
            writeblock(server, input.read(data))
40314
73c2b9c9cd3c py3: convert string literals to bytes in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 28836
diff changeset
   121
        elif ch == b'L':
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   122
            writeblock(server, input.readline(data))
40589
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40317
diff changeset
   123
        elif ch == b'm':
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40317
diff changeset
   124
            bprint(b"message: %r" % data)
40314
73c2b9c9cd3c py3: convert string literals to bytes in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 28836
diff changeset
   125
        elif ch == b'r':
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   126
            ret, = struct.unpack('>i', data)
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   127
            if ret != 0:
40316
09540a5f0a15 py3: reinvent print() function for contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40315
diff changeset
   128
                bprint(b' [%d]' % ret)
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   129
            return ret
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   130
        else:
40316
09540a5f0a15 py3: reinvent print() function for contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40315
diff changeset
   131
            bprint(b"unexpected channel %c: %r" % (ch, data))
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   132
            if ch.isupper():
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   133
                return
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   134
22992
892b2b8c1b50 test-commandserver: allow check() to make connection in different way
Yuya Nishihara <yuya@tcha.org>
parents: 22991
diff changeset
   135
def check(func, connect=connectpipe):
40315
431a831342d2 py3: work around unicode stdio streams in contrib/hgclient.py
Yuya Nishihara <yuya@tcha.org>
parents: 40314
diff changeset
   136
    stdout.flush()
22991
a94594f5d52f test-commandserver: remove unused repopath argument from check()
Yuya Nishihara <yuya@tcha.org>
parents: 22572
diff changeset
   137
    server = connect()
22566
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   138
    try:
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   139
        return func(server)
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   140
    finally:
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   141
        server.stdin.close()
480b7fefbb08 test-commandserver: split helper functions to new hgclient module
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   142
        server.wait()
40589
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40317
diff changeset
   143
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40317
diff changeset
   144
def checkwith(connect=connectpipe, **kwargs):
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40317
diff changeset
   145
    def wrap(func):
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40317
diff changeset
   146
        return check(func, lambda: connect(**kwargs))
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40317
diff changeset
   147
    return wrap