inotify: introduce debuginotify, which lists which paths are under watch
authorNicolas Dumazet <nicdumz.commits@gmail.com>
Wed, 22 Apr 2009 00:37:35 +0900
changeset 8555 3e09bc5fee12
parent 8554 47d7347484f5
child 8556 f5fae700cc00
inotify: introduce debuginotify, which lists which paths are under watch
hgext/inotify/__init__.py
hgext/inotify/client.py
hgext/inotify/common.py
hgext/inotify/server.py
tests/test-inotify-debuginotify
tests/test-inotify-debuginotify.out
--- a/hgext/inotify/__init__.py	Wed Apr 22 00:23:40 2009 +0900
+++ b/hgext/inotify/__init__.py	Wed Apr 22 00:37:35 2009 +0900
@@ -39,6 +39,18 @@
     service = service()
     cmdutil.service(opts, initfn=service.init, runfn=service.run)
 
+def debuginotify(ui, repo, **opts):
+    '''debugging information for inotify extension
+
+    Prints the list of directories being watched by the inotify server.
+    '''
+    cli = client(ui, repo)
+    response = cli.debugquery()
+
+    ui.write(_('directories being watched:\n'))
+    for path in response:
+        ui.write(('  %s/\n') % path)
+
 def reposetup(ui, repo):
     if not hasattr(repo, 'dirstate'):
         return
@@ -82,11 +94,13 @@
     repo.dirstate.__class__ = inotifydirstate
 
 cmdtable = {
+    'debuginotify':
+        (debuginotify, [], ('hg debuginotify')),
     '^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]...')),
+        (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]...')),
     }
--- a/hgext/inotify/client.py	Wed Apr 22 00:23:40 2009 +0900
+++ b/hgext/inotify/client.py	Wed Apr 22 00:37:35 2009 +0900
@@ -142,5 +142,12 @@
                 if names:
                     return filter(match, names.split('\0'))
             return []
+        return map(readnames, resphdr)
 
-        return map(readnames, resphdr)
+    @start_server
+    def debugquery(self):
+        cs, resphdr = self.query('DBUG', '')
+
+        nbytes = resphdr[0]
+        names = cs.read(nbytes)
+        return names.split('\0')
--- a/hgext/inotify/common.py	Wed Apr 22 00:23:40 2009 +0900
+++ b/hgext/inotify/common.py	Wed Apr 22 00:37:35 2009 +0900
@@ -18,6 +18,7 @@
      - For STAT, N+1 \0-separated strings:
         1) N different names that need checking
         2) 1 string containing all the status types to match
+     - No parameter needed for DBUG
 
   Server sending query answer:
   1) send protocol version number
@@ -31,7 +32,8 @@
 version = 2
 
 resphdrfmts = {
-    'STAT': '>llllllll' # status requests
+    'STAT': '>llllllll', # status requests
+    'DBUG': '>l'         # debugging queries
 }
 resphdrsizes = dict((k, struct.calcsize(v))
                     for k, v in resphdrfmts.iteritems())
--- a/hgext/inotify/server.py	Wed Apr 22 00:23:40 2009 +0900
+++ b/hgext/inotify/server.py	Wed Apr 22 00:37:35 2009 +0900
@@ -542,6 +542,13 @@
     def shutdown(self):
         self.watcher.close()
 
+    def debug(self):
+        """
+        Returns a sorted list of relatives paths currently watched,
+        for debugging purposes.
+        """
+        return sorted(tuple[0][len(self.wprefix):] for tuple in self.watcher)
+
 class server(object):
     poll_events = select.POLLIN
 
@@ -624,6 +631,9 @@
             'c' in states and genresult('n', self.repowatcher.tree) or [],
             ]]
 
+    def answer_dbug_query(self):
+        return ['\0'.join(self.repowatcher.debug())]
+
     def handle_event(self, fd, event):
         sock, addr = self.sock.accept()
 
@@ -639,6 +649,8 @@
 
         if type == 'STAT':
             results = self.answer_stat_query(cs)
+        elif type == 'DBUG':
+            results = self.answer_dbug_query()
         else:
             self.ui.warn(_('unrecognized query type: %s\n') % type)
             return
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-inotify-debuginotify	Wed Apr 22 00:37:35 2009 +0900
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+"$TESTDIR/hghave" inotify || exit 80
+
+hg init
+
+echo "[extensions]" >> $HGRCPATH
+echo "inotify=" >> $HGRCPATH
+
+echo % inserve
+hg inserve -d --pid-file=hg.pid
+cat hg.pid >> "$DAEMON_PIDS"
+
+# let the daemon finish its stuff
+sleep 1
+
+echo % empty
+hg debuginotify
+
+mkdir a
+sleep 1
+
+echo % only 'a'
+hg debuginotify
+
+rmdir a
+sleep 1
+
+echo % empty again
+hg debuginotify
+
+kill `cat hg.pid`
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-inotify-debuginotify.out	Wed Apr 22 00:37:35 2009 +0900
@@ -0,0 +1,14 @@
+% inserve
+% empty
+directories being watched:
+  /
+  .hg/
+% only a
+directories being watched:
+  /
+  .hg/
+  a/
+% empty again
+directories being watched:
+  /
+  .hg/