mercurial/chgserver.py
author Gregory Szorc <gregory.szorc@gmail.com>
Wed, 18 Oct 2017 22:57:15 +0200
changeset 34885 df2ff314e36f
parent 34839 110040e715c9
child 34887 7bf7544fd6cc
permissions -rw-r--r--
fsmonitor: warn when fsmonitor could be used fsmonitor can significantly speed up operations on large working directories. But fsmonitor isn't enabled by default, so naive users may not realize there is a potential to make Mercurial faster. This commit introduces a warning to working directory updates when fsmonitor could be used. The following conditions must be met: * Working directory is previously empty * New working directory adds >= N files (currently 50,000) * Running on Linux or MacOS * fsmonitor not enabled * Warning not disabled via config override Because of the empty working directory restriction, most users will only see this warning during `hg clone` (assuming very few users actually do an `hg up null`). The addition of a warning may be considered a BC change. However, clone has printed warnings before. Until recently, Mercurial printed a warning with the server's certificate fingerprint when it wasn't explicitly trusted for example. The warning goes to stderr. So it shouldn't interfere with scripts parsing meaningful output. The OS restriction was on the advice of Facebook engineers, who only feel confident with watchman's stability on the supported platforms. .. feature:: Print warning when fsmonitor isn't being used on a large repository Differential Revision: https://phab.mercurial-scm.org/D894
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     1
# chgserver.py - command server extension for cHg
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     2
#
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     3
# Copyright 2011 Yuya Nishihara <yuya@tcha.org>
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     4
#
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     7
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
     8
"""command server extension for cHg
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     9
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    10
'S' channel (read/write)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    11
    propagate ui.system() request to client
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    12
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    13
'attachio' command
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    14
    attach client's stdio passed by sendmsg()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    15
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    16
'chdir' command
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    17
    change current directory
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    18
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    19
'setenv' command
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    20
    replace os.environ completely
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    21
28325
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    22
'setumask' command
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    23
    set umask
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    24
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
    25
'validate' command
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
    26
    reload the config and check if the server is up to date
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
    27
28325
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    28
Config
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    29
------
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    30
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    31
::
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    32
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    33
  [chgserver]
30990
cb899ee133d8 chgserver: move comments in config example
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
    34
  # how long (in seconds) should an idle chg server exit
cb899ee133d8 chgserver: move comments in config example
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
    35
  idletimeout = 3600
cb899ee133d8 chgserver: move comments in config example
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
    36
cb899ee133d8 chgserver: move comments in config example
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
    37
  # whether to skip config or env change checks
cb899ee133d8 chgserver: move comments in config example
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
    38
  skiphash = False
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    39
"""
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    40
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    41
from __future__ import absolute_import
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    42
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29101
diff changeset
    43
import hashlib
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
    44
import inspect
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    45
import os
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    46
import re
32236
c8b9943c07eb commandserver: move "listen" responsibility from service to handler
Jun Wu <quark@fb.com>
parents: 32208
diff changeset
    47
import socket
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    48
import struct
28223
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
    49
import time
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    50
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
    51
from .i18n import _
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    52
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
    53
from . import (
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    54
    commandserver,
30635
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
    55
    encoding,
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    56
    error,
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
    57
    extensions,
30669
10b17ed9b591 py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30645
diff changeset
    58
    pycompat,
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    59
    util,
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    60
)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    61
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    62
_log = commandserver.log
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    63
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    64
def _hashlist(items):
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    65
    """return sha1 hexdigest for a list"""
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29101
diff changeset
    66
    return hashlib.sha1(str(items)).hexdigest()
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    67
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    68
# sensitive config sections affecting confighash
28478
e6e183687545 chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents: 28454
diff changeset
    69
_configsections = [
29101
57a24a85a2bc chgserver: add [alias] to confighash
Jun Wu <quark@fb.com>
parents: 29088
diff changeset
    70
    'alias',  # affects global state commands.table
34485
37b7581e5737 eol: make [eol] config section sensitive for chg confighash
Jun Wu <quark@fb.com>
parents: 33860
diff changeset
    71
    'eol',    # uses setconfig('eol', ...)
28478
e6e183687545 chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents: 28454
diff changeset
    72
    'extdiff',  # uisetup will register new commands
e6e183687545 chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents: 28454
diff changeset
    73
    'extensions',
e6e183687545 chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents: 28454
diff changeset
    74
]
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    75
34839
110040e715c9 test-show: make it compatible with chg
Jun Wu <quark@fb.com>
parents: 34485
diff changeset
    76
_configsectionitems = [
110040e715c9 test-show: make it compatible with chg
Jun Wu <quark@fb.com>
parents: 34485
diff changeset
    77
    ('commands', 'show.aliasprefix'), # show.py reads it in extsetup
110040e715c9 test-show: make it compatible with chg
Jun Wu <quark@fb.com>
parents: 34485
diff changeset
    78
]
110040e715c9 test-show: make it compatible with chg
Jun Wu <quark@fb.com>
parents: 34485
diff changeset
    79
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    80
# sensitive environment variables affecting confighash
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    81
_envre = re.compile(r'''\A(?:
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    82
                    CHGHG
32271
6096d27dc119 chgserver: more explicit about sensitive environ variables
Jun Wu <quark@fb.com>
parents: 32237
diff changeset
    83
                    |HG(?:DEMANDIMPORT|EMITWARNINGS|MODULEPOLICY|PROF|RCPATH)?
6096d27dc119 chgserver: more explicit about sensitive environ variables
Jun Wu <quark@fb.com>
parents: 32237
diff changeset
    84
                    |HG(?:ENCODING|PLAIN).*
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    85
                    |LANG(?:UAGE)?
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    86
                    |LC_.*
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    87
                    |LD_.*
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    88
                    |PATH
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    89
                    |PYTHON.*
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    90
                    |TERM(?:INFO)?
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    91
                    |TZ
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    92
                    )\Z''', re.X)
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    93
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    94
def _confighash(ui):
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    95
    """return a quick hash for detecting config/env changes
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    96
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    97
    confighash is the hash of sensitive config items and environment variables.
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    98
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    99
    for chgserver, it is designed that once confighash changes, the server is
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   100
    not qualified to serve its client and should redirect the client to a new
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   101
    server. different from mtimehash, confighash change will not mark the
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   102
    server outdated and exit since the user can have different configs at the
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   103
    same time.
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   104
    """
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   105
    sectionitems = []
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   106
    for section in _configsections:
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   107
        sectionitems.append(ui.configitems(section))
34839
110040e715c9 test-show: make it compatible with chg
Jun Wu <quark@fb.com>
parents: 34485
diff changeset
   108
    for section, item in _configsectionitems:
110040e715c9 test-show: make it compatible with chg
Jun Wu <quark@fb.com>
parents: 34485
diff changeset
   109
        sectionitems.append(ui.config(section, item))
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   110
    sectionhash = _hashlist(sectionitems)
30635
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
   111
    envitems = [(k, v) for k, v in encoding.environ.iteritems()
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
   112
                if _envre.match(k)]
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   113
    envhash = _hashlist(sorted(envitems))
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   114
    return sectionhash[:6] + envhash[:6]
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   115
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   116
def _getmtimepaths(ui):
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   117
    """get a list of paths that should be checked to detect change
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   118
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   119
    The list will include:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   120
    - extensions (will not cover all files for complex extensions)
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   121
    - mercurial/__version__.py
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   122
    - python binary
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   123
    """
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   124
    modules = [m for n, m in extensions.extensions(ui)]
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   125
    try:
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
   126
        from . import __version__
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   127
        modules.append(__version__)
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   128
    except ImportError:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   129
        pass
30669
10b17ed9b591 py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30645
diff changeset
   130
    files = [pycompat.sysexecutable]
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   131
    for m in modules:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   132
        try:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   133
            files.append(inspect.getabsfile(m))
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   134
        except TypeError:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   135
            pass
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   136
    return sorted(set(files))
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   137
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   138
def _mtimehash(paths):
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   139
    """return a quick hash for detecting file changes
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   140
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   141
    mtimehash calls stat on given paths and calculate a hash based on size and
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   142
    mtime of each file. mtimehash does not read file content because reading is
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   143
    expensive. therefore it's not 100% reliable for detecting content changes.
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   144
    it's possible to return different hashes for same file contents.
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   145
    it's also possible to return a same hash for different file contents for
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   146
    some carefully crafted situation.
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   147
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   148
    for chgserver, it is designed that once mtimehash changes, the server is
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   149
    considered outdated immediately and should no longer provide service.
29462
71ed5a3ef8a9 chgserver: document why we don't merge mtimehash and confighash
Jun Wu <quark@fb.com>
parents: 29433
diff changeset
   150
71ed5a3ef8a9 chgserver: document why we don't merge mtimehash and confighash
Jun Wu <quark@fb.com>
parents: 29433
diff changeset
   151
    mtimehash is not included in confighash because we only know the paths of
71ed5a3ef8a9 chgserver: document why we don't merge mtimehash and confighash
Jun Wu <quark@fb.com>
parents: 29433
diff changeset
   152
    extensions after importing them (there is imp.find_module but that faces
71ed5a3ef8a9 chgserver: document why we don't merge mtimehash and confighash
Jun Wu <quark@fb.com>
parents: 29433
diff changeset
   153
    race conditions). We need to calculate confighash without importing.
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   154
    """
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   155
    def trystat(path):
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   156
        try:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   157
            st = os.stat(path)
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   158
            return (st.st_mtime, st.st_size)
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   159
        except OSError:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   160
            # could be ENOENT, EPERM etc. not fatal in any case
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   161
            pass
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   162
    return _hashlist(map(trystat, paths))[:12]
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   163
28277
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   164
class hashstate(object):
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   165
    """a structure storing confighash, mtimehash, paths used for mtimehash"""
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   166
    def __init__(self, confighash, mtimehash, mtimepaths):
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   167
        self.confighash = confighash
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   168
        self.mtimehash = mtimehash
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   169
        self.mtimepaths = mtimepaths
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   170
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   171
    @staticmethod
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   172
    def fromui(ui, mtimepaths=None):
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   173
        if mtimepaths is None:
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   174
            mtimepaths = _getmtimepaths(ui)
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   175
        confighash = _confighash(ui)
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   176
        mtimehash = _mtimehash(mtimepaths)
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   177
        _log('confighash = %s mtimehash = %s\n' % (confighash, mtimehash))
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   178
        return hashstate(confighash, mtimehash, mtimepaths)
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   179
30740
493935e0327a chgserver: implement chgui._runpager
Jun Wu <quark@fb.com>
parents: 30739
diff changeset
   180
def _newchgui(srcui, csystem, attachio):
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   181
    class chgui(srcui.__class__):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   182
        def __init__(self, src=None):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   183
            super(chgui, self).__init__(src)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   184
            if src:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   185
                self._csystem = getattr(src, '_csystem', csystem)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   186
            else:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   187
                self._csystem = csystem
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   188
31108
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
   189
        def _runsystem(self, cmd, environ, cwd, out):
28586
82cee85d5274 chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents: 28553
diff changeset
   190
            # fallback to the original system method if the output needs to be
82cee85d5274 chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents: 28553
diff changeset
   191
            # captured (to self._buffers), or the output stream is not stdout
82cee85d5274 chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents: 28553
diff changeset
   192
            # (e.g. stderr, cStringIO), because the chg client is not aware of
82cee85d5274 chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents: 28553
diff changeset
   193
            # these situations and will behave differently (write to stdout).
31107
fbce78c58f1e chg: refactor ui.system() to be partly overridden
Yuya Nishihara <yuya@tcha.org>
parents: 30990
diff changeset
   194
            if (out is not self.fout
28586
82cee85d5274 chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents: 28553
diff changeset
   195
                or not util.safehasattr(self.fout, 'fileno')
30473
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30332
diff changeset
   196
                or self.fout.fileno() != util.stdout.fileno()):
31108
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
   197
                return util.system(cmd, environ=environ, cwd=cwd, out=out)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   198
            self.flush()
31108
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
   199
            return self._csystem(cmd, util.shellenviron(environ), cwd)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   200
31954
e518192d6bac pager: set some environment variables if they're not set
Jun Wu <quark@fb.com>
parents: 31695
diff changeset
   201
        def _runpager(self, cmd, env=None):
e518192d6bac pager: set some environment variables if they're not set
Jun Wu <quark@fb.com>
parents: 31695
diff changeset
   202
            self._csystem(cmd, util.shellenviron(env), type='pager',
30740
493935e0327a chgserver: implement chgui._runpager
Jun Wu <quark@fb.com>
parents: 30739
diff changeset
   203
                          cmdtable={'attachio': attachio})
31690
2d11d278279a ui: defer setting pager related properties until the pager has spawned
Matt Harbison <matt_harbison@yahoo.com>
parents: 31545
diff changeset
   204
            return True
30740
493935e0327a chgserver: implement chgui._runpager
Jun Wu <quark@fb.com>
parents: 30739
diff changeset
   205
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   206
    return chgui(srcui)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   207
28602
83127a9fe76e chgserver: drop old hack to recreate ui on HGPLAIN change
Yuya Nishihara <yuya@tcha.org>
parents: 28599
diff changeset
   208
def _loadnewui(srcui, args):
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
   209
    from . import dispatch  # avoid cycle
30512
cc374292a561 chgserver: delay importing commands and dispatch modules
Yuya Nishihara <yuya@tcha.org>
parents: 30511
diff changeset
   210
30572
cfb227016d01 chgserver: call "load" for new ui objects
Jun Wu <quark@fb.com>
parents: 30513
diff changeset
   211
    newui = srcui.__class__.load()
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   212
    for a in ['fin', 'fout', 'ferr', 'environ']:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   213
        setattr(newui, a, getattr(srcui, a))
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   214
    if util.safehasattr(srcui, '_csystem'):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   215
        newui._csystem = srcui._csystem
28264
3682e201cce6 chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents: 28262
diff changeset
   216
3682e201cce6 chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents: 28262
diff changeset
   217
    # command line args
28767
73bfd9a54a5c chgserver: move args copying logic to the correct place
Jun Wu <quark@fb.com>
parents: 28603
diff changeset
   218
    args = args[:]
28264
3682e201cce6 chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents: 28262
diff changeset
   219
    dispatch._parseconfig(newui, dispatch._earlygetopt(['--config'], args))
3682e201cce6 chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents: 28262
diff changeset
   220
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   221
    # stolen from tortoisehg.util.copydynamicconfig()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   222
    for section, name, value in srcui.walkconfig():
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   223
        source = srcui.configsource(section, name)
31695
d73490957d61 chgserver: do not copy configs set by environment variables
Jun Wu <quark@fb.com>
parents: 31690
diff changeset
   224
        if ':' in source or source == '--config' or source.startswith('$'):
d73490957d61 chgserver: do not copy configs set by environment variables
Jun Wu <quark@fb.com>
parents: 31690
diff changeset
   225
            # path:line or command line, or environ
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   226
            continue
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   227
        newui.setconfig(section, name, value, source)
28599
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   228
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   229
    # load wd and repo config, copied from dispatch.py
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   230
    cwds = dispatch._earlygetopt(['--cwd'], args)
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   231
    cwd = cwds and os.path.realpath(cwds[-1]) or None
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   232
    rpath = dispatch._earlygetopt(["-R", "--repository", "--repo"], args)
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   233
    path, newlui = dispatch._getlocal(newui, rpath, wd=cwd)
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   234
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   235
    return (newui, newlui)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   236
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   237
class channeledsystem(object):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   238
    """Propagate ui.system() request in the following format:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   239
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   240
    payload length (unsigned int),
30726
dd897eb1699e chg: send type information via S channel (BC)
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   241
    type, '\0',
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   242
    cmd, '\0',
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   243
    cwd, '\0',
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   244
    envkey, '=', val, '\0',
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   245
    ...
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   246
    envkey, '=', val
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   247
30726
dd897eb1699e chg: send type information via S channel (BC)
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   248
    if type == 'system', waits for:
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   249
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   250
    exitcode length (unsigned int),
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   251
    exitcode (int)
30739
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   252
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   253
    if type == 'pager', repetitively waits for a command name ending with '\n'
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   254
    and executes it defined by cmdtable, or exits the loop if the command name
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   255
    is empty.
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   256
    """
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   257
    def __init__(self, in_, out, channel):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   258
        self.in_ = in_
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   259
        self.out = out
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   260
        self.channel = channel
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   261
30739
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   262
    def __call__(self, cmd, environ, cwd=None, type='system', cmdtable=None):
30726
dd897eb1699e chg: send type information via S channel (BC)
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   263
        args = [type, util.quotecommand(cmd), os.path.abspath(cwd or '.')]
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   264
        args.extend('%s=%s' % (k, v) for k, v in environ.iteritems())
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   265
        data = '\0'.join(args)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   266
        self.out.write(struct.pack('>cI', self.channel, len(data)))
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   267
        self.out.write(data)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   268
        self.out.flush()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   269
30727
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   270
        if type == 'system':
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   271
            length = self.in_.read(4)
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   272
            length, = struct.unpack('>I', length)
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   273
            if length != 4:
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   274
                raise error.Abort(_('invalid response'))
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   275
            rc, = struct.unpack('>i', self.in_.read(4))
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   276
            return rc
30739
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   277
        elif type == 'pager':
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   278
            while True:
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   279
                cmd = self.in_.readline()[:-1]
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   280
                if not cmd:
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   281
                    break
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   282
                if cmdtable and cmd in cmdtable:
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   283
                    _log('pager subcommand: %s' % cmd)
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   284
                    cmdtable[cmd]()
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   285
                else:
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   286
                    raise error.Abort(_('unexpected command: %s') % cmd)
30727
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   287
        else:
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   288
            raise error.ProgrammingError('invalid S channel type: %s' % type)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   289
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   290
_iochannels = [
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   291
    # server.ch, ui.fp, mode
30924
48dea083f66d py3: convert the mode argument of os.fdopen to unicodes (1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30750
diff changeset
   292
    ('cin', 'fin', pycompat.sysstr('rb')),
48dea083f66d py3: convert the mode argument of os.fdopen to unicodes (1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30750
diff changeset
   293
    ('cout', 'fout', pycompat.sysstr('wb')),
48dea083f66d py3: convert the mode argument of os.fdopen to unicodes (1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30750
diff changeset
   294
    ('cerr', 'ferr', pycompat.sysstr('wb')),
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   295
]
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   296
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   297
class chgcmdserver(commandserver.server):
28328
e00e57d83653 chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents: 28327
diff changeset
   298
    def __init__(self, ui, repo, fin, fout, sock, hashstate, baseaddress):
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   299
        super(chgcmdserver, self).__init__(
30740
493935e0327a chgserver: implement chgui._runpager
Jun Wu <quark@fb.com>
parents: 30739
diff changeset
   300
            _newchgui(ui, channeledsystem(fin, fout, 'S'), self.attachio),
493935e0327a chgserver: implement chgui._runpager
Jun Wu <quark@fb.com>
parents: 30739
diff changeset
   301
            repo, fin, fout)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   302
        self.clientsock = sock
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   303
        self._oldios = []  # original (self.ch, ui.fp, fd) before "attachio"
28328
e00e57d83653 chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents: 28327
diff changeset
   304
        self.hashstate = hashstate
e00e57d83653 chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents: 28327
diff changeset
   305
        self.baseaddress = baseaddress
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   306
        if hashstate is not None:
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   307
            self.capabilities = self.capabilities.copy()
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   308
            self.capabilities['validate'] = chgcmdserver.validate
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   309
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   310
    def cleanup(self):
29512
538d0003c9e0 commandserver: promote .cleanup() hook from chgserver
Yuya Nishihara <yuya@tcha.org>
parents: 29511
diff changeset
   311
        super(chgcmdserver, self).cleanup()
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   312
        # dispatch._runcatch() does not flush outputs if exception is not
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   313
        # handled by dispatch._dispatch()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   314
        self.ui.flush()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   315
        self._restoreio()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   316
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   317
    def attachio(self):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   318
        """Attach to client's stdio passed via unix domain socket; all
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   319
        channels except cresult will no longer be used
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   320
        """
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   321
        # tell client to sendmsg() with 1-byte payload, which makes it
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   322
        # distinctive from "attachio\n" command consumed by client.read()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   323
        self.clientsock.sendall(struct.pack('>cI', 'I', 1))
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31954
diff changeset
   324
        clientfds = util.recvfds(self.clientsock.fileno())
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   325
        _log('received fds: %r\n' % clientfds)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   326
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   327
        ui = self.ui
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   328
        ui.flush()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   329
        first = self._saveio()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   330
        for fd, (cn, fn, mode) in zip(clientfds, _iochannels):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   331
            assert fd > 0
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   332
            fp = getattr(ui, fn)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   333
            os.dup2(fd, fp.fileno())
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   334
            os.close(fd)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   335
            if not first:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   336
                continue
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   337
            # reset buffering mode when client is first attached. as we want
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   338
            # to see output immediately on pager, the mode stays unchanged
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   339
            # when client re-attached. ferr is unchanged because it should
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   340
            # be unbuffered no matter if it is a tty or not.
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   341
            if fn == 'ferr':
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   342
                newfp = fp
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   343
            else:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   344
                # make it line buffered explicitly because the default is
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   345
                # decided on first write(), where fout could be a pager.
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   346
                if fp.isatty():
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   347
                    bufsize = 1  # line buffered
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   348
                else:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   349
                    bufsize = -1  # system default
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   350
                newfp = os.fdopen(fp.fileno(), mode, bufsize)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   351
                setattr(ui, fn, newfp)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   352
            setattr(self, cn, newfp)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   353
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   354
        self.cresult.write(struct.pack('>i', len(clientfds)))
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   355
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   356
    def _saveio(self):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   357
        if self._oldios:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   358
            return False
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   359
        ui = self.ui
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   360
        for cn, fn, _mode in _iochannels:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   361
            ch = getattr(self, cn)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   362
            fp = getattr(ui, fn)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   363
            fd = os.dup(fp.fileno())
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   364
            self._oldios.append((ch, fp, fd))
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   365
        return True
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   366
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   367
    def _restoreio(self):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   368
        ui = self.ui
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   369
        for (ch, fp, fd), (cn, fn, _mode) in zip(self._oldios, _iochannels):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   370
            newfp = getattr(ui, fn)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   371
            # close newfp while it's associated with client; otherwise it
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   372
            # would be closed when newfp is deleted
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   373
            if newfp is not fp:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   374
                newfp.close()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   375
            # restore original fd: fp is open again
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   376
            os.dup2(fd, fp.fileno())
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   377
            os.close(fd)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   378
            setattr(self, cn, ch)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   379
            setattr(ui, fn, fp)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   380
        del self._oldios[:]
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   381
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   382
    def validate(self):
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   383
        """Reload the config and check if the server is up to date
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   384
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   385
        Read a list of '\0' separated arguments.
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   386
        Write a non-empty list of '\0' separated instruction strings or '\0'
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   387
        if the list is empty.
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   388
        An instruction string could be either:
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   389
            - "unlink $path", the client should unlink the path to stop the
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   390
              outdated server.
28535
aa082a8125da chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents: 28516
diff changeset
   391
            - "redirect $path", the client should attempt to connect to $path
aa082a8125da chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents: 28516
diff changeset
   392
              first. If it does not work, start a new server. It implies
aa082a8125da chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents: 28516
diff changeset
   393
              "reconnect".
28516
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   394
            - "exit $n", the client should exit directly with code n.
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   395
              This may happen if we cannot parse the config.
28535
aa082a8125da chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents: 28516
diff changeset
   396
            - "reconnect", the client should close the connection and
aa082a8125da chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents: 28516
diff changeset
   397
              reconnect.
aa082a8125da chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents: 28516
diff changeset
   398
        If neither "reconnect" nor "redirect" is included in the instruction
aa082a8125da chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents: 28516
diff changeset
   399
        list, the client can continue with this server after completing all
aa082a8125da chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents: 28516
diff changeset
   400
        the instructions.
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   401
        """
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
   402
        from . import dispatch  # avoid cycle
30512
cc374292a561 chgserver: delay importing commands and dispatch modules
Yuya Nishihara <yuya@tcha.org>
parents: 30511
diff changeset
   403
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   404
        args = self._readlist()
28516
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   405
        try:
28599
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   406
            self.ui, lui = _loadnewui(self.ui, args)
28516
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   407
        except error.ParseError as inst:
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   408
            dispatch._formatparse(self.ui.warn, inst)
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   409
            self.ui.flush()
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   410
            self.cresult.write('exit 255')
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   411
            return
28599
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   412
        newhash = hashstate.fromui(lui, self.hashstate.mtimepaths)
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   413
        insts = []
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   414
        if newhash.mtimehash != self.hashstate.mtimehash:
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   415
            addr = _hashaddress(self.baseaddress, self.hashstate.confighash)
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   416
            insts.append('unlink %s' % addr)
28536
a979f5b03320 chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents: 28535
diff changeset
   417
            # mtimehash is empty if one or more extensions fail to load.
a979f5b03320 chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents: 28535
diff changeset
   418
            # to be compatible with hg, still serve the client this time.
a979f5b03320 chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents: 28535
diff changeset
   419
            if self.hashstate.mtimehash:
a979f5b03320 chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents: 28535
diff changeset
   420
                insts.append('reconnect')
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   421
        if newhash.confighash != self.hashstate.confighash:
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   422
            addr = _hashaddress(self.baseaddress, newhash.confighash)
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   423
            insts.append('redirect %s' % addr)
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   424
        _log('validate: %s\n' % insts)
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   425
        self.cresult.write('\0'.join(insts) or '\0')
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   426
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   427
    def chdir(self):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   428
        """Change current directory
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   429
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   430
        Note that the behavior of --cwd option is bit different from this.
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   431
        It does not affect --config parameter.
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   432
        """
28158
7cc57a531f0c chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents: 28014
diff changeset
   433
        path = self._readstr()
7cc57a531f0c chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents: 28014
diff changeset
   434
        if not path:
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   435
            return
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   436
        _log('chdir to %r\n' % path)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   437
        os.chdir(path)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   438
28159
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   439
    def setumask(self):
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   440
        """Change umask"""
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   441
        mask = struct.unpack('>I', self._read(4))[0]
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   442
        _log('setumask %r\n' % mask)
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   443
        os.umask(mask)
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   444
30644
2bb8c53be961 chgserver: override runcommand
Jun Wu <quark@fb.com>
parents: 30643
diff changeset
   445
    def runcommand(self):
2bb8c53be961 chgserver: override runcommand
Jun Wu <quark@fb.com>
parents: 30643
diff changeset
   446
        return super(chgcmdserver, self).runcommand()
2bb8c53be961 chgserver: override runcommand
Jun Wu <quark@fb.com>
parents: 30643
diff changeset
   447
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   448
    def setenv(self):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   449
        """Clear and update os.environ
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   450
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   451
        Note that not all variables can make an effect on the running process.
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   452
        """
28158
7cc57a531f0c chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents: 28014
diff changeset
   453
        l = self._readlist()
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   454
        try:
28158
7cc57a531f0c chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents: 28014
diff changeset
   455
            newenv = dict(s.split('=', 1) for s in l)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   456
        except ValueError:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   457
            raise ValueError('unexpected value in setenv request')
28602
83127a9fe76e chgserver: drop old hack to recreate ui on HGPLAIN change
Yuya Nishihara <yuya@tcha.org>
parents: 28599
diff changeset
   458
        _log('setenv: %r\n' % sorted(newenv.keys()))
30635
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
   459
        encoding.environ.clear()
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
   460
        encoding.environ.update(newenv)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   461
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   462
    capabilities = commandserver.server.capabilities.copy()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   463
    capabilities.update({'attachio': attachio,
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   464
                         'chdir': chdir,
30644
2bb8c53be961 chgserver: override runcommand
Jun Wu <quark@fb.com>
parents: 30643
diff changeset
   465
                         'runcommand': runcommand,
28159
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   466
                         'setenv': setenv,
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   467
                         'setumask': setumask})
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   468
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31954
diff changeset
   469
    if util.safehasattr(util, 'setprocname'):
30750
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   470
        def setprocname(self):
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   471
            """Change process title"""
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   472
            name = self._readstr()
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   473
            _log('setprocname: %r\n' % name)
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31954
diff changeset
   474
            util.setprocname(name)
30750
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   475
        capabilities['setprocname'] = setprocname
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   476
28223
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   477
def _tempaddress(address):
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   478
    return '%s.%d.tmp' % (address, os.getpid())
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   479
28326
ea400a4f32e6 chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents: 28325
diff changeset
   480
def _hashaddress(address, hashstr):
30619
88efb4fb1975 chgserver: truncate base address at "." for hash address
Jun Wu <quark@fb.com>
parents: 30618
diff changeset
   481
    # if the basename of address contains '.', use only the left part. this
88efb4fb1975 chgserver: truncate base address at "." for hash address
Jun Wu <quark@fb.com>
parents: 30618
diff changeset
   482
    # makes it possible for the client to pass 'server.tmp$PID' and follow by
88efb4fb1975 chgserver: truncate base address at "." for hash address
Jun Wu <quark@fb.com>
parents: 30618
diff changeset
   483
    # an atomic rename to avoid locking when spawning new servers.
88efb4fb1975 chgserver: truncate base address at "." for hash address
Jun Wu <quark@fb.com>
parents: 30618
diff changeset
   484
    dirname, basename = os.path.split(address)
88efb4fb1975 chgserver: truncate base address at "." for hash address
Jun Wu <quark@fb.com>
parents: 30618
diff changeset
   485
    basename = basename.split('.', 1)[0]
88efb4fb1975 chgserver: truncate base address at "." for hash address
Jun Wu <quark@fb.com>
parents: 30618
diff changeset
   486
    return '%s-%s' % (os.path.join(dirname, basename), hashstr)
28326
ea400a4f32e6 chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents: 28325
diff changeset
   487
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   488
class chgunixservicehandler(object):
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   489
    """Set of operations for chg services"""
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   490
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   491
    pollinterval = 1  # [sec]
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   492
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   493
    def __init__(self, ui):
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   494
        self.ui = ui
33499
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 32271
diff changeset
   495
        self._idletimeout = ui.configint('chgserver', 'idletimeout')
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   496
        self._lastactive = time.time()
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   497
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   498
    def bindsocket(self, sock, address):
29597
581c0c7cb258 chgserver: refactor initialization of real/base addresses
Yuya Nishihara <yuya@tcha.org>
parents: 29596
diff changeset
   499
        self._inithashstate(address)
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   500
        self._checkextensions()
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   501
        self._bind(sock)
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   502
        self._createsymlink()
32237
1ada3d18e7fb commandserver: move printbanner logic to bindsocket
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
   503
        # no "listening at" message should be printed to simulate hg behavior
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   504
29597
581c0c7cb258 chgserver: refactor initialization of real/base addresses
Yuya Nishihara <yuya@tcha.org>
parents: 29596
diff changeset
   505
    def _inithashstate(self, address):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   506
        self._baseaddress = address
33499
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 32271
diff changeset
   507
        if self.ui.configbool('chgserver', 'skiphash'):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   508
            self._hashstate = None
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   509
            self._realaddress = address
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   510
            return
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   511
        self._hashstate = hashstate.fromui(self.ui)
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   512
        self._realaddress = _hashaddress(address, self._hashstate.confighash)
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   513
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   514
    def _checkextensions(self):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   515
        if not self._hashstate:
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   516
            return
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   517
        if extensions.notloaded():
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   518
            # one or more extensions failed to load. mtimehash becomes
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   519
            # meaningless because we do not know the paths of those extensions.
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   520
            # set mtimehash to an illegal hash value to invalidate the server.
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   521
            self._hashstate.mtimehash = ''
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   522
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   523
    def _bind(self, sock):
28223
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   524
        # use a unique temp address so we can stat the file and do ownership
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   525
        # check later
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   526
        tempaddress = _tempaddress(self._realaddress)
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   527
        util.bindunixsocket(sock, tempaddress)
29529
02de1dbd4f6e chgserver: narrow scope of chdir() to socket.bind()
Yuya Nishihara <yuya@tcha.org>
parents: 29513
diff changeset
   528
        self._socketstat = os.stat(tempaddress)
32236
c8b9943c07eb commandserver: move "listen" responsibility from service to handler
Jun Wu <quark@fb.com>
parents: 32208
diff changeset
   529
        sock.listen(socket.SOMAXCONN)
29529
02de1dbd4f6e chgserver: narrow scope of chdir() to socket.bind()
Yuya Nishihara <yuya@tcha.org>
parents: 29513
diff changeset
   530
        # rename will replace the old socket file if exists atomically. the
02de1dbd4f6e chgserver: narrow scope of chdir() to socket.bind()
Yuya Nishihara <yuya@tcha.org>
parents: 29513
diff changeset
   531
        # old server will detect ownership change and exit.
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   532
        util.rename(tempaddress, self._realaddress)
28223
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   533
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   534
    def _createsymlink(self):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   535
        if self._baseaddress == self._realaddress:
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   536
            return
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   537
        tempaddress = _tempaddress(self._baseaddress)
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   538
        os.symlink(os.path.basename(self._realaddress), tempaddress)
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   539
        util.rename(tempaddress, self._baseaddress)
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   540
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   541
    def _issocketowner(self):
28223
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   542
        try:
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   543
            stat = os.stat(self._realaddress)
28223
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   544
            return (stat.st_ino == self._socketstat.st_ino and
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   545
                    stat.st_mtime == self._socketstat.st_mtime)
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   546
        except OSError:
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   547
            return False
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   548
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   549
    def unlinksocket(self, address):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   550
        if not self._issocketowner():
28223
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   551
            return
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   552
        # it is possible to have a race condition here that we may
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   553
        # remove another server's socket file. but that's okay
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   554
        # since that server will detect and exit automatically and
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   555
        # the client will start a new server on demand.
31545
82b3ec04b652 chgserver: use tryunlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31108
diff changeset
   556
        util.tryunlink(self._realaddress)
28223
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   557
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   558
    def shouldexit(self):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   559
        if not self._issocketowner():
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   560
            self.ui.debug('%s is not owned, exiting.\n' % self._realaddress)
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   561
            return True
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   562
        if time.time() - self._lastactive > self._idletimeout:
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   563
            self.ui.debug('being idle too long. exiting.\n')
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   564
            return True
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   565
        return False
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   566
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   567
    def newconnection(self):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   568
        self._lastactive = time.time()
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   569
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   570
    def createcmdserver(self, repo, conn, fin, fout):
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   571
        return chgcmdserver(self.ui, repo, fin, fout, conn,
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   572
                            self._hashstate, self._baseaddress)
28223
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   573
29546
a7513390a9db chgserver: extract stub factory of service object
Yuya Nishihara <yuya@tcha.org>
parents: 29545
diff changeset
   574
def chgunixservice(ui, repo, opts):
33860
3cfc9070245f demandimport: disable if chg is being used
Jun Wu <quark@fb.com>
parents: 33499
diff changeset
   575
    # CHGINTERNALMARK is set by chg client. It is an indication of things are
3cfc9070245f demandimport: disable if chg is being used
Jun Wu <quark@fb.com>
parents: 33499
diff changeset
   576
    # started by chg so other code can do things accordingly, like disabling
3cfc9070245f demandimport: disable if chg is being used
Jun Wu <quark@fb.com>
parents: 33499
diff changeset
   577
    # demandimport or detecting chg client started by chg client. When executed
3cfc9070245f demandimport: disable if chg is being used
Jun Wu <quark@fb.com>
parents: 33499
diff changeset
   578
    # here, CHGINTERNALMARK is no longer useful and hence dropped to make
3cfc9070245f demandimport: disable if chg is being used
Jun Wu <quark@fb.com>
parents: 33499
diff changeset
   579
    # environ cleaner.
30635
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
   580
    if 'CHGINTERNALMARK' in encoding.environ:
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
   581
        del encoding.environ['CHGINTERNALMARK']
30511
1873563e1ede chgserver: drop CHGINTERNALMARK by chgunixservice()
Yuya Nishihara <yuya@tcha.org>
parents: 30507
diff changeset
   582
29546
a7513390a9db chgserver: extract stub factory of service object
Yuya Nishihara <yuya@tcha.org>
parents: 29545
diff changeset
   583
    if repo:
30332
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 29841
diff changeset
   584
        # one chgserver can serve multiple repos. drop repo information
29546
a7513390a9db chgserver: extract stub factory of service object
Yuya Nishihara <yuya@tcha.org>
parents: 29545
diff changeset
   585
        ui.setconfig('bundle', 'mainreporoot', '', 'repo')
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   586
    h = chgunixservicehandler(ui)
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   587
    return commandserver.unixforkingservice(ui, repo=None, opts=opts, handler=h)