hgext/fsmonitor/watchmanclient.py
author Martin von Zweigbergk <martinvonz@google.com>
Wed, 02 May 2018 23:17:58 -0700
changeset 37968 0304f22497fa
parent 30649 b0a0f7b9ed90
child 41968 57264906a996
permissions -rw-r--r--
revlog: use node tree (native code) for shortest() calculation I want to rewrite revlog.shortest() to disambiguate only among hex nodeids and then disambiguate the result with revnums at a higher level (in scmutil). However, that would slow down `hg log -T '{shortest(node,1)}\n'` from 5.0s to 6.8s, which I wasn't sure would be acceptable. So this patch makes revlog.shortest() use the node tree for finding the length of the shortest prefix that's unambiguous among nodeids. Once that has been found, it makes it longer until it is also not ambiguous with a revnum. This speeds up `hg log -T '{shortest(node,1)}\n'` from 5.0s to 4.0s. Differential Revision: https://phab.mercurial-scm.org/D3499
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     1
# watchmanclient.py - Watchman client for the fsmonitor extension
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     2
#
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     3
# Copyright 2013-2016 Facebook, Inc.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     4
#
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     7
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     8
from __future__ import absolute_import
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     9
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    10
import getpass
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    11
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    12
from mercurial import util
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    13
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    14
from . import pywatchman
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    15
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    16
class Unavailable(Exception):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    17
    def __init__(self, msg, warn=True, invalidate=False):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    18
        self.msg = msg
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    19
        self.warn = warn
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    20
        if self.msg == 'timed out waiting for response':
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    21
            self.warn = False
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    22
        self.invalidate = invalidate
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    23
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    24
    def __str__(self):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    25
        if self.warn:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    26
            return 'warning: Watchman unavailable: %s' % self.msg
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    27
        else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    28
            return 'Watchman unavailable: %s' % self.msg
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    29
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    30
class WatchmanNoRoot(Unavailable):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    31
    def __init__(self, root, msg):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    32
        self.root = root
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    33
        super(WatchmanNoRoot, self).__init__(msg)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    34
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    35
class client(object):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    36
    def __init__(self, repo, timeout=1.0):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    37
        err = None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    38
        if not self._user:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    39
            err = "couldn't get user"
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    40
            warn = True
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    41
        if self._user in repo.ui.configlist('fsmonitor', 'blacklistusers'):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    42
            err = 'user %s in blacklist' % self._user
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    43
            warn = False
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    44
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    45
        if err:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    46
            raise Unavailable(err, warn)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    47
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    48
        self._timeout = timeout
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    49
        self._watchmanclient = None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    50
        self._root = repo.root
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    51
        self._ui = repo.ui
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    52
        self._firsttime = True
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    53
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    54
    def settimeout(self, timeout):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    55
        self._timeout = timeout
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    56
        if self._watchmanclient is not None:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    57
            self._watchmanclient.setTimeout(timeout)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    58
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    59
    def getcurrentclock(self):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    60
        result = self.command('clock')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    61
        if not util.safehasattr(result, 'clock'):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    62
            raise Unavailable('clock result is missing clock value',
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    63
                              invalidate=True)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    64
        return result.clock
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    65
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    66
    def clearconnection(self):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    67
        self._watchmanclient = None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    68
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    69
    def available(self):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    70
        return self._watchmanclient is not None or self._firsttime
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    71
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    72
    @util.propertycache
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    73
    def _user(self):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    74
        try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    75
            return getpass.getuser()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    76
        except KeyError:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    77
            # couldn't figure out our user
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    78
            return None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    79
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    80
    def _command(self, *args):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    81
        watchmanargs = (args[0], self._root) + args[1:]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    82
        try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    83
            if self._watchmanclient is None:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    84
                self._firsttime = False
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    85
                self._watchmanclient = pywatchman.client(
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    86
                    timeout=self._timeout,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    87
                    useImmutableBser=True)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    88
            return self._watchmanclient.query(*watchmanargs)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    89
        except pywatchman.CommandError as ex:
30649
b0a0f7b9ed90 fsmonitor: fix exception message scraping
zphricz <zack.hricz@oculus.com>
parents: 28433
diff changeset
    90
            if 'unable to resolve root' in ex.msg:
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    91
                raise WatchmanNoRoot(self._root, ex.msg)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    92
            raise Unavailable(ex.msg)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    93
        except pywatchman.WatchmanError as ex:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    94
            raise Unavailable(str(ex))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    95
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    96
    def command(self, *args):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    97
        try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    98
            try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    99
                return self._command(*args)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   100
            except WatchmanNoRoot:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   101
                # this 'watch' command can also raise a WatchmanNoRoot if
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   102
                # watchman refuses to accept this root
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   103
                self._command('watch')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   104
                return self._command(*args)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   105
        except Unavailable:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   106
            # this is in an outer scope to catch Unavailable form any of the
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   107
            # above _command calls
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   108
            self._watchmanclient = None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   109
            raise