hgext/inotify/__init__.py
changeset 6239 39cfcef4f463
child 6603 41eb20cc1c02
child 6995 25619b72f86a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext/inotify/__init__.py	Wed Mar 12 15:30:11 2008 -0700
@@ -0,0 +1,104 @@
+# __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]...')),
+    }