Merge pull request #1053 from ZyX-I/fix-uv-watcher
Some fixes for libuv-based watcher
This commit is contained in:
commit
77d311bdc8
|
@ -45,6 +45,7 @@ Common configuration is a subdictionary that is a value of ``common`` key in
|
|||
auto Selects most performant watcher.
|
||||
inotify Select inotify watcher. Linux only.
|
||||
stat Select stat-based polling watcher.
|
||||
uv Select libuv-based watcher.
|
||||
======= ===================================
|
||||
|
||||
Default is ``auto``.
|
||||
|
|
|
@ -19,6 +19,8 @@ Generic requirements
|
|||
repositories.
|
||||
* ``bzr`` python package (note: *not* standalone executable). Required to work
|
||||
with bazaar repositories.
|
||||
* ``pyuv`` python package. Required for :ref:`libuv-based watcher
|
||||
<config-common-watcher>` to work.
|
||||
* ``i3-py``, `available on github <https://github.com/ziberna/i3-py>`_. Required
|
||||
for i3wm bindings and segments.
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ def get_branch_name(directory, config_file, get_func, create_watcher):
|
|||
with branch_lock:
|
||||
# Check if the repo directory was moved/deleted
|
||||
fw = branch_watcher(create_watcher)
|
||||
is_watched = fw.is_watched(directory)
|
||||
is_watched = fw.is_watching(directory)
|
||||
try:
|
||||
changed = fw(directory)
|
||||
except OSError as e:
|
||||
|
|
|
@ -18,16 +18,17 @@ def create_file_watcher(pl, watcher_type='auto', expire_time=10):
|
|||
|
||||
Use ``.unwatch()`` method of the returned object to stop watching the file.
|
||||
|
||||
Uses inotify if available, otherwise tracks mtimes. expire_time is the
|
||||
number of minutes after the last query for a given path for the inotify
|
||||
watch for that path to be automatically removed. This conserves kernel
|
||||
resources.
|
||||
Uses inotify if available, then pyuv, otherwise tracks mtimes. expire_time
|
||||
is the number of minutes after the last query for a given path for the
|
||||
inotify watch for that path to be automatically removed. This conserves
|
||||
kernel resources.
|
||||
|
||||
:param PowerlineLogger pl:
|
||||
Logger.
|
||||
:param str watcher_type:
|
||||
One of ``inotify`` (linux only), ``stat``, ``auto``. Determines what
|
||||
watcher will be used. ``auto`` will use ``inotify`` if available.
|
||||
:param str watcher_type
|
||||
One of ``inotify`` (linux only), ``uv``, ``stat``, ``auto``. Determines
|
||||
what watcher will be used. ``auto`` will use ``inotify`` if available,
|
||||
then ``libuv`` and then fall back to ``stat``.
|
||||
:param int expire_time:
|
||||
Number of minutes since last ``.__call__()`` before inotify watcher will
|
||||
stop watching given file.
|
||||
|
@ -67,7 +68,7 @@ def create_tree_watcher(pl, watcher_type='auto', expire_time=10):
|
|||
Logger.
|
||||
:param str watcher_type:
|
||||
Watcher type. Currently the only supported types are ``inotify`` (linux
|
||||
only), ``dummy`` and ``auto``.
|
||||
only), ``uv``, ``dummy`` and ``auto``.
|
||||
:param int expire_time:
|
||||
Number of minutes since last ``.__call__()`` before inotify watcher will
|
||||
stop watching given file.
|
||||
|
|
|
@ -101,7 +101,7 @@ class INotifyFileWatcher(INotify):
|
|||
self.watches[path] = wd
|
||||
self.modified[path] = False
|
||||
|
||||
def is_watched(self, path):
|
||||
def is_watching(self, path):
|
||||
with self.lock:
|
||||
return realpath(path) in self.watches
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ class StatFileWatcher(object):
|
|||
with self.lock:
|
||||
self.watches.pop(path, None)
|
||||
|
||||
def is_watched(self, path):
|
||||
def is_watching(self, path):
|
||||
with self.lock:
|
||||
return realpath(path) in self.watches
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ class UvWatcher(object):
|
|||
self.loop = start_uv_thread()
|
||||
|
||||
def watch(self, path):
|
||||
path = realpath(path)
|
||||
with self.lock:
|
||||
if path not in self.watches:
|
||||
try:
|
||||
|
@ -80,6 +81,7 @@ class UvWatcher(object):
|
|||
raise
|
||||
|
||||
def unwatch(self, path):
|
||||
path = realpath(path)
|
||||
with self.lock:
|
||||
try:
|
||||
watch = self.watches.pop(path)
|
||||
|
@ -87,6 +89,10 @@ class UvWatcher(object):
|
|||
return
|
||||
watch.close(partial(self._stopped_watching, path))
|
||||
|
||||
def is_watching(self, path):
|
||||
with self.lock:
|
||||
return realpath(path) in self.watches
|
||||
|
||||
def __del__(self):
|
||||
try:
|
||||
lock = self.lock
|
||||
|
@ -115,6 +121,7 @@ class UvFileWatcher(UvWatcher):
|
|||
self.events.pop(path, None)
|
||||
|
||||
def __call__(self, path):
|
||||
path = realpath(path)
|
||||
with self.lock:
|
||||
events = self.events.pop(path, None)
|
||||
if events:
|
||||
|
@ -122,6 +129,7 @@ class UvFileWatcher(UvWatcher):
|
|||
if path not in self.watches:
|
||||
self.watch(path)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class UvTreeWatcher(UvWatcher):
|
||||
|
@ -135,7 +143,7 @@ class UvTreeWatcher(UvWatcher):
|
|||
self.watch_directory(self.basedir)
|
||||
|
||||
def watch_directory(self, path):
|
||||
os.path.walk(path, self.watch_one_directory, None)
|
||||
os.path.walk(realpath(path), self.watch_one_directory, None)
|
||||
|
||||
def watch_one_directory(self, arg, dirname, fnames):
|
||||
try:
|
||||
|
|
|
@ -141,6 +141,40 @@ class TestFilesystemWatchers(TestCase):
|
|||
tw = create_tree_watcher(get_fallback_logger(), 'uv')
|
||||
return self.do_test_tree_watcher(tw)
|
||||
|
||||
def test_inotify_file_watcher_is_watching(self):
|
||||
try:
|
||||
w = create_file_watcher(pl=get_fallback_logger(), watcher_type='inotify')
|
||||
except INotifyError:
|
||||
raise SkipTest('INotify is not available')
|
||||
return self.do_test_file_watcher_is_watching(w)
|
||||
|
||||
def test_stat_file_watcher_is_watching(self):
|
||||
w = create_file_watcher(pl=get_fallback_logger(), watcher_type='stat')
|
||||
return self.do_test_file_watcher_is_watching(w)
|
||||
|
||||
def test_uv_file_watcher_is_watching(self):
|
||||
try:
|
||||
w = create_file_watcher(pl=get_fallback_logger(), watcher_type='uv')
|
||||
except UvNotFound:
|
||||
raise SkipTest('Pyuv is not available')
|
||||
return self.do_test_file_watcher_is_watching(w)
|
||||
|
||||
def do_test_file_watcher_is_watching(self, w):
|
||||
try:
|
||||
f1, f2, f3 = map(lambda x: os.path.join(INOTIFY_DIR, 'file%d' % x), (1, 2, 3))
|
||||
with open(f1, 'wb'):
|
||||
with open(f2, 'wb'):
|
||||
with open(f3, 'wb'):
|
||||
pass
|
||||
ne = os.path.join(INOTIFY_DIR, 'notexists')
|
||||
self.assertRaises(OSError, w, ne)
|
||||
self.assertTrue(w(f1))
|
||||
self.assertFalse(w.is_watching(ne))
|
||||
self.assertTrue(w.is_watching(f1))
|
||||
self.assertFalse(w.is_watching(f2))
|
||||
finally:
|
||||
clear_dir(INOTIFY_DIR)
|
||||
|
||||
|
||||
old_cwd = None
|
||||
|
||||
|
|
Loading…
Reference in New Issue