hgext/inotify/__init__.py
author Gilles Moris <gilles.moris@free.fr>
Thu, 03 Apr 2008 11:11:31 +0200
changeset 6456 db5324d3c257
parent 6239 39cfcef4f463
child 6603 41eb20cc1c02
child 6995 25619b72f86a
permissions -rw-r--r--
Pager extension: switch it off if --debugger is set The pager is preventing the debugger prompt and much of the debugger output to be refreshed. Moreover the pager does not make sense when debugging line by line. (This supersedes the similar ui.debugflag patch. Disabling the pager for debug output doesn't make that much sense, as this is actually when the pager might be useful.)

# __init__.py - inotify-based status acceleration for Linux
#
# Copyright 2006, 2007, 2008 Bryan O'Sullivan <bos@serpentine.com>
# Copyright 2007, 2008 Brendan Cully <brendan@kublai.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.

'''inotify-based status acceleration for Linux systems
'''

# todo: socket permissions

from mercurial.i18n import gettext as _
from mercurial import cmdutil, util
import client, errno, os, server, socket
from weakref import proxy

def serve(ui, repo, **opts):
    '''start an inotify server for this repository'''
    timeout = opts.get('timeout')
    if timeout:
        timeout = float(timeout) * 1e3

    class service:
        def init(self):
            self.master = server.Master(ui, repo, timeout)

        def run(self):
            try:
                self.master.run()
            finally:
                self.master.shutdown()

    service = service()
    cmdutil.service(opts, initfn=service.init, runfn=service.run)

def reposetup(ui, repo):
    if not repo.local():
        return

    # XXX: weakref until hg stops relying on __del__
    repo = proxy(repo)

    class inotifydirstate(repo.dirstate.__class__):
        # Set to True if we're the inotify server, so we don't attempt
        # to recurse.
        inotifyserver = False

        def status(self, files, match, list_ignored, list_clean,
                   list_unknown=True):
            try:
                if not list_ignored and not self.inotifyserver:
                    result = client.query(ui, repo, files, match, False,
                                          list_clean, list_unknown)
                    if result is not None:
                        return result
            except socket.error, err:
                if err[0] == errno.ECONNREFUSED:
                    ui.warn(_('(found dead inotify server socket; '
                                   'removing it)\n'))
                    os.unlink(repo.join('inotify.sock'))
                elif err[0] != errno.ENOENT:
                    raise
                if ui.configbool('inotify', 'autostart'):
                    query = None
                    ui.debug(_('(starting inotify server)\n'))
                    try:
                        server.start(ui, repo)
                        query = client.query
                    except server.AlreadyStartedException, inst:
                        # another process may have started its own
                        # inotify server while this one was starting.
                        ui.debug(str(inst))
                        query = client.query
                    except Exception, inst:
                        ui.warn(_('could not start inotify server: '
                                       '%s\n') % inst)
                        ui.print_exc()

                    if query:
                        try:
                            return query(ui, repo, files or [], match,
                                         list_ignored, list_clean, list_unknown)
                        except socket.error, err:
                            ui.warn(_('could not talk to new inotify '
                                           'server: %s\n') % err[1])
                            ui.print_exc()

            return super(inotifydirstate, self).status(
                files, match or util.always, list_ignored, list_clean,
                list_unknown)

    repo.dirstate.__class__ = inotifydirstate

cmdtable = {
    '^inserve':
    (serve,
     [('d', 'daemon', None, _('run server in background')),
      ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
      ('t', 'idle-timeout', '', _('minutes to sit idle before exiting')),
      ('', 'pid-file', '', _('name of file to write process ID to'))],
     _('hg inserve [OPT]...')),
    }