##// END OF EJS Templates
inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet -
r8555:3e09bc5f default
parent child Browse files
Show More
@@ -0,0 +1,32 b''
1 #!/bin/sh
2
3 "$TESTDIR/hghave" inotify || exit 80
4
5 hg init
6
7 echo "[extensions]" >> $HGRCPATH
8 echo "inotify=" >> $HGRCPATH
9
10 echo % inserve
11 hg inserve -d --pid-file=hg.pid
12 cat hg.pid >> "$DAEMON_PIDS"
13
14 # let the daemon finish its stuff
15 sleep 1
16
17 echo % empty
18 hg debuginotify
19
20 mkdir a
21 sleep 1
22
23 echo % only 'a'
24 hg debuginotify
25
26 rmdir a
27 sleep 1
28
29 echo % empty again
30 hg debuginotify
31
32 kill `cat hg.pid`
@@ -0,0 +1,14 b''
1 % inserve
2 % empty
3 directories being watched:
4 /
5 .hg/
6 % only a
7 directories being watched:
8 /
9 .hg/
10 a/
11 % empty again
12 directories being watched:
13 /
14 .hg/
@@ -39,6 +39,18 b' def serve(ui, repo, **opts):'
39 service = service()
39 service = service()
40 cmdutil.service(opts, initfn=service.init, runfn=service.run)
40 cmdutil.service(opts, initfn=service.init, runfn=service.run)
41
41
42 def debuginotify(ui, repo, **opts):
43 '''debugging information for inotify extension
44
45 Prints the list of directories being watched by the inotify server.
46 '''
47 cli = client(ui, repo)
48 response = cli.debugquery()
49
50 ui.write(_('directories being watched:\n'))
51 for path in response:
52 ui.write((' %s/\n') % path)
53
42 def reposetup(ui, repo):
54 def reposetup(ui, repo):
43 if not hasattr(repo, 'dirstate'):
55 if not hasattr(repo, 'dirstate'):
44 return
56 return
@@ -82,11 +94,13 b' def reposetup(ui, repo):'
82 repo.dirstate.__class__ = inotifydirstate
94 repo.dirstate.__class__ = inotifydirstate
83
95
84 cmdtable = {
96 cmdtable = {
97 'debuginotify':
98 (debuginotify, [], ('hg debuginotify')),
85 '^inserve':
99 '^inserve':
86 (serve,
100 (serve,
87 [('d', 'daemon', None, _('run server in background')),
101 [('d', 'daemon', None, _('run server in background')),
88 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
102 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
89 ('t', 'idle-timeout', '', _('minutes to sit idle before exiting')),
103 ('t', 'idle-timeout', '', _('minutes to sit idle before exiting')),
90 ('', 'pid-file', '', _('name of file to write process ID to'))],
104 ('', 'pid-file', '', _('name of file to write process ID to'))],
91 _('hg inserve [OPT]...')),
105 _('hg inserve [OPT]...')),
92 }
106 }
@@ -142,5 +142,12 b' class client(object):'
142 if names:
142 if names:
143 return filter(match, names.split('\0'))
143 return filter(match, names.split('\0'))
144 return []
144 return []
145 return map(readnames, resphdr)
145
146
146 return map(readnames, resphdr)
147 @start_server
148 def debugquery(self):
149 cs, resphdr = self.query('DBUG', '')
150
151 nbytes = resphdr[0]
152 names = cs.read(nbytes)
153 return names.split('\0')
@@ -18,6 +18,7 b' import cStringIO, socket, struct'
18 - For STAT, N+1 \0-separated strings:
18 - For STAT, N+1 \0-separated strings:
19 1) N different names that need checking
19 1) N different names that need checking
20 2) 1 string containing all the status types to match
20 2) 1 string containing all the status types to match
21 - No parameter needed for DBUG
21
22
22 Server sending query answer:
23 Server sending query answer:
23 1) send protocol version number
24 1) send protocol version number
@@ -31,7 +32,8 b' import cStringIO, socket, struct'
31 version = 2
32 version = 2
32
33
33 resphdrfmts = {
34 resphdrfmts = {
34 'STAT': '>llllllll' # status requests
35 'STAT': '>llllllll', # status requests
36 'DBUG': '>l' # debugging queries
35 }
37 }
36 resphdrsizes = dict((k, struct.calcsize(v))
38 resphdrsizes = dict((k, struct.calcsize(v))
37 for k, v in resphdrfmts.iteritems())
39 for k, v in resphdrfmts.iteritems())
@@ -542,6 +542,13 b' class repowatcher(object):'
542 def shutdown(self):
542 def shutdown(self):
543 self.watcher.close()
543 self.watcher.close()
544
544
545 def debug(self):
546 """
547 Returns a sorted list of relatives paths currently watched,
548 for debugging purposes.
549 """
550 return sorted(tuple[0][len(self.wprefix):] for tuple in self.watcher)
551
545 class server(object):
552 class server(object):
546 poll_events = select.POLLIN
553 poll_events = select.POLLIN
547
554
@@ -624,6 +631,9 b' class server(object):'
624 'c' in states and genresult('n', self.repowatcher.tree) or [],
631 'c' in states and genresult('n', self.repowatcher.tree) or [],
625 ]]
632 ]]
626
633
634 def answer_dbug_query(self):
635 return ['\0'.join(self.repowatcher.debug())]
636
627 def handle_event(self, fd, event):
637 def handle_event(self, fd, event):
628 sock, addr = self.sock.accept()
638 sock, addr = self.sock.accept()
629
639
@@ -639,6 +649,8 b' class server(object):'
639
649
640 if type == 'STAT':
650 if type == 'STAT':
641 results = self.answer_stat_query(cs)
651 results = self.answer_stat_query(cs)
652 elif type == 'DBUG':
653 results = self.answer_dbug_query()
642 else:
654 else:
643 self.ui.warn(_('unrecognized query type: %s\n') % type)
655 self.ui.warn(_('unrecognized query type: %s\n') % type)
644 return
656 return
General Comments 0
You need to be logged in to leave comments. Login now