hgext/inotify/__init__.py
author Thomas Arendsen Hein <thomas@intevation.de>
Fri, 07 Nov 2008 13:02:04 +0100
changeset 7329 fd4bf5269733
parent 7304 68374f1c8c87
child 7393 92c952c4470c
permissions -rw-r--r--
Do not abort with inotify extension enabled, but not supported by the system. And remove the "native support is required" message which is generated at an inappropriate location and is printed more than once when using 'hg status'.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     1
# __init__.py - inotify-based status acceleration for Linux
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     2
#
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     3
# Copyright 2006, 2007, 2008 Bryan O'Sullivan <bos@serpentine.com>
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     4
# Copyright 2007, 2008 Brendan Cully <brendan@kublai.com>
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     5
#
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     6
# This software may be used and distributed according to the terms
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     7
# of the GNU General Public License, incorporated herein by reference.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     8
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     9
'''inotify-based status acceleration for Linux systems
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    10
'''
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    11
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    12
# todo: socket permissions
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    13
7225
59b4ae211584 i18n: import _ instead of gettext
Martin Geisler <mg@daimi.au.dk>
parents: 7219
diff changeset
    14
from mercurial.i18n import _
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    15
from mercurial import cmdutil, util
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    16
import client, errno, os, server, socket
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    17
from weakref import proxy
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    18
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    19
def serve(ui, repo, **opts):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    20
    '''start an inotify server for this repository'''
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    21
    timeout = opts.get('timeout')
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    22
    if timeout:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    23
        timeout = float(timeout) * 1e3
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    24
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    25
    class service:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    26
        def init(self):
6995
25619b72f86a inotify: fix traceback when the server has been already started
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6239
diff changeset
    27
            try:
25619b72f86a inotify: fix traceback when the server has been already started
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6239
diff changeset
    28
                self.master = server.Master(ui, repo, timeout)
25619b72f86a inotify: fix traceback when the server has been already started
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6239
diff changeset
    29
            except server.AlreadyStartedException, inst:
25619b72f86a inotify: fix traceback when the server has been already started
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6239
diff changeset
    30
                raise util.Abort(str(inst))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    31
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    32
        def run(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    33
            try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    34
                self.master.run()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    35
            finally:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    36
                self.master.shutdown()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    37
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    38
    service = service()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    39
    cmdutil.service(opts, initfn=service.init, runfn=service.run)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    40
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    41
def reposetup(ui, repo):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    42
    if not repo.local():
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    43
        return
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    44
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    45
    # XXX: weakref until hg stops relying on __del__
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    46
    repo = proxy(repo)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    47
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    48
    class inotifydirstate(repo.dirstate.__class__):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    49
        # Set to True if we're the inotify server, so we don't attempt
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    50
        # to recurse.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    51
        inotifyserver = False
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    52
6753
ed5ffb2c12f3 repo.status: eliminate list_
Matt Mackall <mpm@selenic.com>
parents: 6603
diff changeset
    53
        def status(self, match, ignored, clean, unknown=True):
6603
41eb20cc1c02 match: remove files arg from repo.status and friends
Matt Mackall <mpm@selenic.com>
parents: 6239
diff changeset
    54
            files = match.files()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    55
            try:
6753
ed5ffb2c12f3 repo.status: eliminate list_
Matt Mackall <mpm@selenic.com>
parents: 6603
diff changeset
    56
                if not ignored and not self.inotifyserver:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    57
                    result = client.query(ui, repo, files, match, False,
6753
ed5ffb2c12f3 repo.status: eliminate list_
Matt Mackall <mpm@selenic.com>
parents: 6603
diff changeset
    58
                                          clean, unknown)
7219
1f6d2e487135 inotify: add debugging mode to inotify
Matt Mackall <mpm@selenic.com>
parents: 7218
diff changeset
    59
                    if ui.config('inotify', 'debug'):
1f6d2e487135 inotify: add debugging mode to inotify
Matt Mackall <mpm@selenic.com>
parents: 7218
diff changeset
    60
                        r2 = super(inotifydirstate, self).status(
1f6d2e487135 inotify: add debugging mode to inotify
Matt Mackall <mpm@selenic.com>
parents: 7218
diff changeset
    61
                            match, False, clean, unknown)
1f6d2e487135 inotify: add debugging mode to inotify
Matt Mackall <mpm@selenic.com>
parents: 7218
diff changeset
    62
                        for c,a,b in zip('LMARDUIC', result, r2):
1f6d2e487135 inotify: add debugging mode to inotify
Matt Mackall <mpm@selenic.com>
parents: 7218
diff changeset
    63
                            for f in a:
1f6d2e487135 inotify: add debugging mode to inotify
Matt Mackall <mpm@selenic.com>
parents: 7218
diff changeset
    64
                                if f not in b:
1f6d2e487135 inotify: add debugging mode to inotify
Matt Mackall <mpm@selenic.com>
parents: 7218
diff changeset
    65
                                    ui.warn('*** inotify: %s +%s\n' % (c, f))
1f6d2e487135 inotify: add debugging mode to inotify
Matt Mackall <mpm@selenic.com>
parents: 7218
diff changeset
    66
                            for f in b:
1f6d2e487135 inotify: add debugging mode to inotify
Matt Mackall <mpm@selenic.com>
parents: 7218
diff changeset
    67
                                if f not in a:
7304
68374f1c8c87 inotify: fix bug in formatting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7225
diff changeset
    68
                                    ui.warn('*** inotify: %s -%s\n' % (c, f))
7219
1f6d2e487135 inotify: add debugging mode to inotify
Matt Mackall <mpm@selenic.com>
parents: 7218
diff changeset
    69
                        result = r2
1f6d2e487135 inotify: add debugging mode to inotify
Matt Mackall <mpm@selenic.com>
parents: 7218
diff changeset
    70
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    71
                    if result is not None:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    72
                        return result
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6996
diff changeset
    73
            except (OSError, socket.error), err:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    74
                if err[0] == errno.ECONNREFUSED:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    75
                    ui.warn(_('(found dead inotify server socket; '
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    76
                                   'removing it)\n'))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    77
                    os.unlink(repo.join('inotify.sock'))
6996
fecf060f32a1 inotify: deactivate inotify status on failure
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6995
diff changeset
    78
                if err[0] in (errno.ECONNREFUSED, errno.ENOENT) and \
7218
1bd7f90465b3 inotify: auto-start by default when enabled
Matt Mackall <mpm@selenic.com>
parents: 7217
diff changeset
    79
                        ui.configbool('inotify', 'autostart', True):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    80
                    query = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    81
                    ui.debug(_('(starting inotify server)\n'))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    82
                    try:
7329
fd4bf5269733 Do not abort with inotify extension enabled, but not supported by the system.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7304
diff changeset
    83
                        try:
fd4bf5269733 Do not abort with inotify extension enabled, but not supported by the system.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7304
diff changeset
    84
                            server.start(ui, repo)
fd4bf5269733 Do not abort with inotify extension enabled, but not supported by the system.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7304
diff changeset
    85
                            query = client.query
fd4bf5269733 Do not abort with inotify extension enabled, but not supported by the system.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7304
diff changeset
    86
                        except server.AlreadyStartedException, inst:
fd4bf5269733 Do not abort with inotify extension enabled, but not supported by the system.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7304
diff changeset
    87
                            # another process may have started its own
fd4bf5269733 Do not abort with inotify extension enabled, but not supported by the system.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7304
diff changeset
    88
                            # inotify server while this one was starting.
fd4bf5269733 Do not abort with inotify extension enabled, but not supported by the system.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7304
diff changeset
    89
                            ui.debug(str(inst))
fd4bf5269733 Do not abort with inotify extension enabled, but not supported by the system.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7304
diff changeset
    90
                            query = client.query
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    91
                    except Exception, inst:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    92
                        ui.warn(_('could not start inotify server: '
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    93
                                       '%s\n') % inst)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    94
                    if query:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    95
                        try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    96
                            return query(ui, repo, files or [], match,
6753
ed5ffb2c12f3 repo.status: eliminate list_
Matt Mackall <mpm@selenic.com>
parents: 6603
diff changeset
    97
                                         ignored, clean, unknown)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    98
                        except socket.error, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    99
                            ui.warn(_('could not talk to new inotify '
6996
fecf060f32a1 inotify: deactivate inotify status on failure
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6995
diff changeset
   100
                                           'server: %s\n') % err[-1])
7217
9fa2f8dcb869 inotify: friendlier message when daemon not running
Matt Mackall <mpm@selenic.com>
parents: 7083
diff changeset
   101
                elif err[0] == errno.ENOENT:
9fa2f8dcb869 inotify: friendlier message when daemon not running
Matt Mackall <mpm@selenic.com>
parents: 7083
diff changeset
   102
                    ui.warn(_('(inotify server not running)\n'))
6996
fecf060f32a1 inotify: deactivate inotify status on failure
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6995
diff changeset
   103
                else:
fecf060f32a1 inotify: deactivate inotify status on failure
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6995
diff changeset
   104
                    ui.warn(_('failed to contact inotify server: %s\n')
fecf060f32a1 inotify: deactivate inotify status on failure
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6995
diff changeset
   105
                             % err[-1])
fecf060f32a1 inotify: deactivate inotify status on failure
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6995
diff changeset
   106
                ui.print_exc()
fecf060f32a1 inotify: deactivate inotify status on failure
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6995
diff changeset
   107
                # replace by old status function
fecf060f32a1 inotify: deactivate inotify status on failure
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6995
diff changeset
   108
                self.status = super(inotifydirstate, self).status
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   109
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   110
            return super(inotifydirstate, self).status(
6753
ed5ffb2c12f3 repo.status: eliminate list_
Matt Mackall <mpm@selenic.com>
parents: 6603
diff changeset
   111
                match, ignored, clean, unknown)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   112
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   113
    repo.dirstate.__class__ = inotifydirstate
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   114
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   115
cmdtable = {
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   116
    '^inserve':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   117
    (serve,
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   118
     [('d', 'daemon', None, _('run server in background')),
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   119
      ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   120
      ('t', 'idle-timeout', '', _('minutes to sit idle before exiting')),
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   121
      ('', 'pid-file', '', _('name of file to write process ID to'))],
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   122
     _('hg inserve [OPT]...')),
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   123
    }