annotate hgext/inotify/server.py @ 18096:cd53e40ab0e2

inotify: don't fall over just because of a dangling symlink Previously, the inotify server failed to start if .hg/inotify.sock was a symlink that pointed to a non-existent path. This behaviour does not seem to make any sense. Now, if we encounter a broken symlink, we unlink it and continue.
author Bryan O'Sullivan <bryano@fb.com>
date Tue, 18 Dec 2012 17:33:32 -0800
parents cfb6682961b8
children ae54cff742e2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
1 # server.py - common entry point for inotify status server
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
2 #
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
3 # Copyright 2009 Nicolas Dumazet <nicdumz@gmail.com>
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9900
diff changeset
6 # GNU General Public License version 2 or any later version.
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
7
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
8 from mercurial.i18n import _
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
9 from mercurial import cmdutil, osutil, util
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
10 import common
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
11
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
12 import errno
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
13 import os
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
14 import socket
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
15 import stat
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
16 import struct
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
17 import sys
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
18 import tempfile
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
19
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
20 class AlreadyStartedException(Exception):
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
21 pass
10494
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
22 class TimeoutException(Exception):
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
23 pass
6239
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 def join(a, b):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
26 if a:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
27 if a[-1] == '/':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
28 return a + b
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
29 return a + '/' + b
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
30 return b
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
31
8787
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
32 def split(path):
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
33 c = path.rfind('/')
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
34 if c == -1:
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
35 return '', path
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
36 return path[:c], path[c + 1:]
8787
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
37
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
38 walk_ignored_errors = (errno.ENOENT, errno.ENAMETOOLONG)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
39
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
40 def walk(dirstate, absroot, root):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
41 '''Like os.walk, but only yields regular files.'''
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
42
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
43 # This function is critical to performance during startup.
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 def walkit(root, reporoot):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
46 files, dirs = [], []
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 try:
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
49 fullpath = join(absroot, root)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
50 for name, kind in osutil.listdir(fullpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
51 if kind == stat.S_IFDIR:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
52 if name == '.hg':
8325
f2559645643a inotify: inotify.server.walk() simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8324
diff changeset
53 if not reporoot:
8323
589a82fb02a2 inotify: inotify.server.walk*() cleanup
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8322
diff changeset
54 return
8325
f2559645643a inotify: inotify.server.walk() simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8324
diff changeset
55 else:
f2559645643a inotify: inotify.server.walk() simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8324
diff changeset
56 dirs.append(name)
8381
f52fcc864df4 inotify: server.walk(): use yield instead of for
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8336
diff changeset
57 path = join(root, name)
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
58 if dirstate._ignore(path):
8381
f52fcc864df4 inotify: server.walk(): use yield instead of for
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8336
diff changeset
59 continue
f52fcc864df4 inotify: server.walk(): use yield instead of for
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8336
diff changeset
60 for result in walkit(path, False):
f52fcc864df4 inotify: server.walk(): use yield instead of for
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8336
diff changeset
61 yield result
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
62 elif kind in (stat.S_IFREG, stat.S_IFLNK):
8334
0695288e8c37 inotify: inotify.server.walk() filetype is never used, do not yield it
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8325
diff changeset
63 files.append(name)
8324
b923d599c309 inotify: inotify.server.walk*() remove unnecessary var
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8323
diff changeset
64 yield fullpath, dirs, files
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
65
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
66 except OSError, err:
9116
f90bbf1ea09f inotify: fix issue1375, add a test.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9115
diff changeset
67 if err.errno == errno.ENOTDIR:
f90bbf1ea09f inotify: fix issue1375, add a test.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9115
diff changeset
68 # fullpath was a directory, but has since been replaced
f90bbf1ea09f inotify: fix issue1375, add a test.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9115
diff changeset
69 # by a file.
f90bbf1ea09f inotify: fix issue1375, add a test.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9115
diff changeset
70 yield fullpath, dirs, files
f90bbf1ea09f inotify: fix issue1375, add a test.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9115
diff changeset
71 elif err.errno not in walk_ignored_errors:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
72 raise
8320
a1305c1c8d8e inotify: inotify.server.walk() simplify algorithm
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8319
diff changeset
73
a1305c1c8d8e inotify: inotify.server.walk() simplify algorithm
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8319
diff changeset
74 return walkit(root, root == '')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
75
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
76 class directory(object):
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
77 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
78 Representing a directory
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
79
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
80 * path is the relative path from repo root to this directory
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
81 * files is a dict listing the files in this directory
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
82 - keys are file names
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
83 - values are file status
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
84 * dirs is a dict listing the subdirectories
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
85 - key are subdirectories names
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
86 - values are directory objects
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
87 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
88 def __init__(self, relpath=''):
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
89 self.path = relpath
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
90 self.files = {}
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
91 self.dirs = {}
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
92
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
93 def dir(self, relpath):
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
94 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
95 Returns the directory contained at the relative path relpath.
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
96 Creates the intermediate directories if necessary.
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
97 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
98 if not relpath:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
99 return self
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
100 l = relpath.split('/')
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
101 ret = self
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
102 while l:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
103 next = l.pop(0)
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
104 try:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
105 ret = ret.dirs[next]
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
106 except KeyError:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
107 d = directory(join(ret.path, next))
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
108 ret.dirs[next] = d
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
109 ret = d
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
110 return ret
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
111
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
112 def walk(self, states, visited=None):
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
113 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
114 yield (filename, status) pairs for items in the trees
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
115 that have status in states.
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
116 filenames are relative to the repo root
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
117 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
118 for file, st in self.files.iteritems():
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
119 if st in states:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
120 yield join(self.path, file), st
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
121 for dir in self.dirs.itervalues():
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
122 if visited is not None:
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
123 visited.add(dir.path)
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
124 for e in dir.walk(states):
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
125 yield e
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
126
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
127 def lookup(self, states, path, visited):
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
128 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
129 yield root-relative filenames that match path, and whose
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
130 status are in states:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
131 * if path is a file, yield path
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
132 * if path is a directory, yield directory files
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
133 * if path is not tracked, yield nothing
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
134 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
135 if path[-1] == '/':
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
136 path = path[:-1]
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
137
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
138 paths = path.split('/')
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
139
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
140 # we need to check separately for last node
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
141 last = paths.pop()
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
142
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
143 tree = self
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
144 try:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
145 for dir in paths:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
146 tree = tree.dirs[dir]
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
147 except KeyError:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
148 # path is not tracked
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
149 visited.add(tree.path)
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
150 return
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
151
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
152 try:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
153 # if path is a directory, walk it
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
154 target = tree.dirs[last]
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
155 visited.add(target.path)
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
156 for file, st in target.walk(states, visited):
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
157 yield file
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
158 except KeyError:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
159 try:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
160 if tree.files[last] in states:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
161 # path is a file
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
162 visited.add(tree.path)
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
163 yield path
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
164 except KeyError:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
165 # path is not tracked
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
166 pass
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
167
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
168 class repowatcher(object):
8610
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
169 """
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
170 Watches inotify events
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
171 """
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
172 statuskeys = 'almr!?'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
173
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
174 def __init__(self, ui, dirstate, root):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
175 self.ui = ui
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
176 self.dirstate = dirstate
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
177
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
178 self.wprefix = join(root, '')
9349
56fb15ad8fb1 inotify: server: use wprefix everywhere, introduce prefixlen
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9348
diff changeset
179 self.prefixlen = len(self.wprefix)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
180
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
181 self.tree = directory()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
182 self.statcache = {}
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
183 self.statustrees = dict([(s, directory()) for s in self.statuskeys])
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
184
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
185 self.ds_info = self.dirstate_info()
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
186
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
187 self.last_event = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
188
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
189
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
190 def handle_timeout(self):
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
191 pass
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
192
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
193 def dirstate_info(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
194 try:
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
195 st = os.lstat(self.wprefix + '.hg/dirstate')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
196 return st.st_mtime, st.st_ino
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
197 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
198 if err.errno != errno.ENOENT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
199 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
200 return 0, 0
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
201
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
202 def filestatus(self, fn, st):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
203 try:
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
204 type_, mode, size, time = self.dirstate._map[fn][:4]
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
205 except KeyError:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
206 type_ = '?'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
207 if type_ == 'n':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
208 st_mode, st_size, st_mtime = st
7082
be81b4788115 inotify: fix confusion on files in lookup state
Matt Mackall <mpm@selenic.com>
parents: 6998
diff changeset
209 if size == -1:
be81b4788115 inotify: fix confusion on files in lookup state
Matt Mackall <mpm@selenic.com>
parents: 6998
diff changeset
210 return 'l'
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
211 if size and (size != st_size or (mode ^ st_mode) & 0100):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
212 return 'm'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
213 if time != int(st_mtime):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
214 return 'l'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
215 return 'n'
11545
db9d16233787 inotify: check all components of filenames against hgignore (issue884)
Renato Cunha <renatoc@gmail.com>
parents: 10494
diff changeset
216 if type_ == '?' and self.dirstate._dirignore(fn):
db9d16233787 inotify: check all components of filenames against hgignore (issue884)
Renato Cunha <renatoc@gmail.com>
parents: 10494
diff changeset
217 # we must check not only if the file is ignored, but if any part
db9d16233787 inotify: check all components of filenames against hgignore (issue884)
Renato Cunha <renatoc@gmail.com>
parents: 10494
diff changeset
218 # of its path match an ignore pattern
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
219 return 'i'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
220 return type_
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
221
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
222 def updatefile(self, wfn, osstat):
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
223 '''
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
224 update the file entry of an existing file.
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
225
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
226 osstat: (mode, size, time) tuple, as returned by os.lstat(wfn)
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
227 '''
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
228
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
229 self._updatestatus(wfn, self.filestatus(wfn, osstat))
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
230
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
231 def deletefile(self, wfn, oldstatus):
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
232 '''
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
233 update the entry of a file which has been deleted.
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
234
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
235 oldstatus: char in statuskeys, status of the file before deletion
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
236 '''
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
237 if oldstatus == 'r':
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
238 newstatus = 'r'
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
239 elif oldstatus in 'almn':
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
240 newstatus = '!'
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
241 else:
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
242 newstatus = None
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
243
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
244 self.statcache.pop(wfn, None)
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
245 self._updatestatus(wfn, newstatus)
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
246
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
247 def _updatestatus(self, wfn, newstatus):
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
248 '''
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
249 Update the stored status of a file.
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
250
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
251 newstatus: - char in (statuskeys + 'ni'), new status to apply.
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
252 - or None, to stop tracking wfn
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
253 '''
8787
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
254 root, fn = split(wfn)
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
255 d = self.tree.dir(root)
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
256
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
257 oldstatus = d.files.get(fn)
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
258 # oldstatus can be either:
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
259 # - None : fn is new
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
260 # - a char in statuskeys: fn is a (tracked) file
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
261
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
262 if self.ui.debugflag and oldstatus != newstatus:
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
263 self.ui.note(_('status: %r %s -> %s\n') %
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
264 (wfn, oldstatus, newstatus))
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
265
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
266 if oldstatus and oldstatus in self.statuskeys \
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
267 and oldstatus != newstatus:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
268 del self.statustrees[oldstatus].dir(root).files[fn]
9348
954f7a879495 inotify: server._updatestatus: simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9117
diff changeset
269
954f7a879495 inotify: server._updatestatus: simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9117
diff changeset
270 if newstatus in (None, 'i'):
954f7a879495 inotify: server._updatestatus: simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9117
diff changeset
271 d.files.pop(fn, None)
954f7a879495 inotify: server._updatestatus: simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9117
diff changeset
272 elif oldstatus != newstatus:
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
273 d.files[fn] = newstatus
9348
954f7a879495 inotify: server._updatestatus: simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9117
diff changeset
274 if newstatus != 'n':
954f7a879495 inotify: server._updatestatus: simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9117
diff changeset
275 self.statustrees[newstatus].dir(root).files[fn] = newstatus
7892
67e59a9886d5 Fixing issue1542, adding a relevant test
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7451
diff changeset
276
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
277 def check_deleted(self, key):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
278 # Files that had been deleted but were present in the dirstate
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
279 # may have vanished from the dirstate; we must clean them up.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
280 nuke = []
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
281 for wfn, ignore in self.statustrees[key].walk(key):
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
282 if wfn not in self.dirstate:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
283 nuke.append(wfn)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
284 for wfn in nuke:
8787
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
285 root, fn = split(wfn)
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
286 del self.statustrees[key].dir(root).files[fn]
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
287 del self.tree.dir(root).files[fn]
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
288
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
289 def update_hgignore(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
290 # An update of the ignore file can potentially change the
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
291 # states of all unknown and ignored files.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
292
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
293 # XXX If the user has other ignore files outside the repo, or
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
294 # changes their list of ignore files at run time, we'll
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
295 # potentially never see changes to them. We could get the
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
296 # client to report to us what ignore data they're using.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
297 # But it's easier to do nothing than to open that can of
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
298 # worms.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
299
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
300 if '_ignore' in self.dirstate.__dict__:
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
301 delattr(self.dirstate, '_ignore')
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
302 self.ui.note(_('rescanning due to .hgignore change\n'))
8604
578f2a0049cd inotify: do not recurse in handle_timeout(): call it explicitely, not in scan()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8600
diff changeset
303 self.handle_timeout()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
304 self.scan()
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
305
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
306 def getstat(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
307 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
308 return self.statcache[wpath]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
309 except KeyError:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
310 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
311 return self.stat(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
312 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
313 if err.errno != errno.ENOENT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
314 raise
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
315
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
316 def stat(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
317 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
318 st = os.lstat(join(self.wprefix, wpath))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
319 ret = st.st_mode, st.st_size, st.st_mtime
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
320 self.statcache[wpath] = ret
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
321 return ret
7280
810ca383da9c remove unused variables
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7220
diff changeset
322 except OSError:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
323 self.statcache.pop(wpath, None)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
324 raise
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
325
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
326 class socketlistener(object):
8610
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
327 """
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
328 Listens for client queries on unix socket inotify.sock
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
329 """
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
330 def __init__(self, ui, root, repowatcher, timeout):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
331 self.ui = ui
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
332 self.repowatcher = repowatcher
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
333 self.sock = socket.socket(socket.AF_UNIX)
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
334 self.sockpath = join(root, '.hg/inotify.sock')
12650
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
335
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
336 self.realsockpath = self.sockpath
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
337 if os.path.islink(self.sockpath):
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
338 if os.path.exists(self.sockpath):
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
339 self.realsockpath = os.readlink(self.sockpath)
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
340 else:
18096
cd53e40ab0e2 inotify: don't fall over just because of a dangling symlink
Bryan O'Sullivan <bryano@fb.com>
parents: 16688
diff changeset
341 os.unlink(self.sockpath)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
342 try:
12650
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
343 self.sock.bind(self.realsockpath)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
344 except socket.error, err:
11567
34cc8b84407f removed exception args indexing (not supported by py3k)
Renato Cunha <renatoc@gmail.com>
parents: 11545
diff changeset
345 if err.args[0] == errno.EADDRINUSE:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
346 raise AlreadyStartedException(_('cannot start: socket is '
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
347 'already bound'))
11567
34cc8b84407f removed exception args indexing (not supported by py3k)
Renato Cunha <renatoc@gmail.com>
parents: 11545
diff changeset
348 if err.args[0] == "AF_UNIX path too long":
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
349 tempdir = tempfile.mkdtemp(prefix="hg-inotify-")
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
350 self.realsockpath = os.path.join(tempdir, "inotify.sock")
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
351 try:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
352 self.sock.bind(self.realsockpath)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
353 os.symlink(self.realsockpath, self.sockpath)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
354 except (OSError, socket.error), inst:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
355 try:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
356 os.unlink(self.realsockpath)
16688
cfb6682961b8 cleanup: replace naked excepts with more specific ones
Brodie Rao <brodie@sf.io>
parents: 15151
diff changeset
357 except OSError:
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
358 pass
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
359 os.rmdir(tempdir)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
360 if inst.errno == errno.EEXIST:
9900
8939900073a8 inotify: improve error messages
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9897
diff changeset
361 raise AlreadyStartedException(_('cannot start: tried '
8939900073a8 inotify: improve error messages
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9897
diff changeset
362 'linking .hg/inotify.sock to a temporary socket but'
8939900073a8 inotify: improve error messages
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9897
diff changeset
363 ' .hg/inotify.sock already exists'))
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
364 raise
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
365 else:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
366 raise
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
367 self.sock.listen(5)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
368 self.fileno = self.sock.fileno
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
369
8554
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
370 def answer_stat_query(self, cs):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
371 names = cs.read().split('\0')
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
372
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
373 states = names.pop()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
374
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
375 self.ui.note(_('answering query for %r\n') % states)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
376
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
377 visited = set()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
378 if not names:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
379 def genresult(states, tree):
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
380 for fn, state in tree.walk(states):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
381 yield fn
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
382 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
383 def genresult(states, tree):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
384 for fn in names:
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
385 for f in tree.lookup(states, fn, visited):
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
386 yield f
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
387
8554
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
388 return ['\0'.join(r) for r in [
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
389 genresult('l', self.repowatcher.statustrees['l']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
390 genresult('m', self.repowatcher.statustrees['m']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
391 genresult('a', self.repowatcher.statustrees['a']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
392 genresult('r', self.repowatcher.statustrees['r']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
393 genresult('!', self.repowatcher.statustrees['!']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
394 '?' in states
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
395 and genresult('?', self.repowatcher.statustrees['?'])
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
396 or [],
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
397 [],
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
398 'c' in states and genresult('n', self.repowatcher.tree) or [],
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
399 visited
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
400 ]]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
401
8555
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
402 def answer_dbug_query(self):
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
403 return ['\0'.join(self.repowatcher.debug())]
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
404
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
405 def accept_connection(self):
8554
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
406 sock, addr = self.sock.accept()
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
407
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
408 cs = common.recvcs(sock)
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
409 version = ord(cs.read(1))
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
410
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
411 if version != common.version:
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
412 self.ui.warn(_('received query from incompatible client '
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
413 'version %d\n') % version)
8952
7c7a672e9db7 inotify: return version to client even when not matching
Simon Heimberg <simohe@besonet.ch>
parents: 8794
diff changeset
414 try:
7c7a672e9db7 inotify: return version to client even when not matching
Simon Heimberg <simohe@besonet.ch>
parents: 8794
diff changeset
415 # try to send back our version to the client
7c7a672e9db7 inotify: return version to client even when not matching
Simon Heimberg <simohe@besonet.ch>
parents: 8794
diff changeset
416 # this way, the client too is informed of the mismatch
7c7a672e9db7 inotify: return version to client even when not matching
Simon Heimberg <simohe@besonet.ch>
parents: 8794
diff changeset
417 sock.sendall(chr(common.version))
16688
cfb6682961b8 cleanup: replace naked excepts with more specific ones
Brodie Rao <brodie@sf.io>
parents: 15151
diff changeset
418 except socket.error:
8952
7c7a672e9db7 inotify: return version to client even when not matching
Simon Heimberg <simohe@besonet.ch>
parents: 8794
diff changeset
419 pass
8554
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
420 return
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
421
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
422 type = cs.read(4)
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
423
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
424 if type == 'STAT':
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
425 results = self.answer_stat_query(cs)
8555
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
426 elif type == 'DBUG':
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
427 results = self.answer_dbug_query()
8554
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
428 else:
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
429 self.ui.warn(_('unrecognized query type: %s\n') % type)
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
430 return
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
431
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
432 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
433 try:
8386
4aad982111b6 inotify: Abstract the layer format and sizes to a inotify.common dictionary
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8385
diff changeset
434 v = chr(common.version)
4aad982111b6 inotify: Abstract the layer format and sizes to a inotify.common dictionary
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8385
diff changeset
435
8553
e387ecd7a6ed inotify: change protocol so that different query types can be supported.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8386
diff changeset
436 sock.sendall(v + type + struct.pack(common.resphdrfmts[type],
e387ecd7a6ed inotify: change protocol so that different query types can be supported.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8386
diff changeset
437 *map(len, results)))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
438 sock.sendall(''.join(results))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
439 finally:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
440 sock.shutdown(socket.SHUT_WR)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
441 except socket.error, err:
11567
34cc8b84407f removed exception args indexing (not supported by py3k)
Renato Cunha <renatoc@gmail.com>
parents: 11545
diff changeset
442 if err.args[0] != errno.EPIPE:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
443 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
444
15151
0d4f6e843b05 building: build inotify for sys.platform='linux*'
Nikolaj Sjujskij <sterkrig@myopera.com>
parents: 12650
diff changeset
445 if sys.platform.startswith('linux'):
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
446 import linuxserver as _server
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
447 else:
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
448 raise ImportError
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
449
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
450 master = _server.master
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
451
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
452 def start(ui, dirstate, root, opts):
10494
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
453 timeout = opts.get('idle_timeout')
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
454 if timeout:
10494
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
455 timeout = float(timeout) * 60000
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
456 else:
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
457 timeout = None
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
458
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
459 class service(object):
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
460 def init(self):
7451
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
461 try:
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
462 self.master = master(ui, dirstate, root, timeout)
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
463 except AlreadyStartedException, inst:
9900
8939900073a8 inotify: improve error messages
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9897
diff changeset
464 raise util.Abort("inotify-server: %s" % inst)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
465
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
466 def run(self):
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
467 try:
10494
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
468 try:
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
469 self.master.run()
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
470 except TimeoutException:
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
471 pass
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
472 finally:
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
473 self.master.shutdown()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
474
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
475 if 'inserve' not in sys.argv:
10239
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10090
diff changeset
476 runargs = util.hgcmd() + ['inserve', '-R', root]
9897
97eda2133a9b inotify: add a inotify.pidfile configuration possibility
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9854
diff changeset
477 else:
10239
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10090
diff changeset
478 runargs = util.hgcmd() + sys.argv[1:]
9897
97eda2133a9b inotify: add a inotify.pidfile configuration possibility
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9854
diff changeset
479
97eda2133a9b inotify: add a inotify.pidfile configuration possibility
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9854
diff changeset
480 pidfile = ui.config('inotify', 'pidfile')
97eda2133a9b inotify: add a inotify.pidfile configuration possibility
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9854
diff changeset
481 if opts['daemon'] and pidfile is not None and 'pid-file' not in runargs:
97eda2133a9b inotify: add a inotify.pidfile configuration possibility
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9854
diff changeset
482 runargs.append("--pid-file=%s" % pidfile)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
483
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
484 service = service()
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
485 logfile = ui.config('inotify', 'log')
10013
b2e87fde6806 run-tests: --inotify: use inotify.appendpid to append pids to $DAEMON_PIDS
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9933
diff changeset
486
b2e87fde6806 run-tests: --inotify: use inotify.appendpid to append pids to $DAEMON_PIDS
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9933
diff changeset
487 appendpid = ui.configbool('inotify', 'appendpid', False)
b2e87fde6806 run-tests: --inotify: use inotify.appendpid to append pids to $DAEMON_PIDS
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9933
diff changeset
488
11943
2d3cbcace897 inotify: show the exact command used to start the server
Greg Ward <greg-hg@gerg.ca>
parents: 11567
diff changeset
489 ui.debug('starting inotify server: %s\n' % ' '.join(runargs))
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
490 cmdutil.service(opts, initfn=service.init, runfn=service.run,
10013
b2e87fde6806 run-tests: --inotify: use inotify.appendpid to append pids to $DAEMON_PIDS
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9933
diff changeset
491 logfile=logfile, runargs=runargs, appendpid=appendpid)