# HG changeset patch # User Goffi # Date 1588164873 -7200 # Node ID a1606e2a92ebfe5ed36b830e9b8efd1cc866aafa # Parent 821b6ce57f99400ac2456f48245b024371ab3472 server: fixed watching a directory which is already watched: Twisted file watched is not adding a callback to a watched path when there is already one, but this can happens often in Libervia, as a whole site is recusively watched in dev mode, and tasks may want to add other watchers. To work around this, the new `_checkCallback` will recursively check that callback has been indeed added to the requested path. diff -r 821b6ce57f99 -r a1606e2a92eb libervia/server/server.py --- a/libervia/server/server.py Mon Apr 27 10:55:23 2020 +0200 +++ b/libervia/server/server.py Wed Apr 29 14:54:33 2020 +0200 @@ -90,14 +90,40 @@ notifier.startReading() return self._notifier + def _checkCallback(self, dir_path, callback, recursive): + # Twisted doesn't add callback if a watcher was already set on a path + # but in dev mode Libervia watches whole sites + internal path can be watched + # by tasks, so several callbacks must be called on some paths. + # This method check that the new callback is indeed present in the desired path + # and add it otherwise. + # FIXME: this should probably be fixed upstream + if recursive: + for child in dir_path.walk(): + if child.isdir(): + self._checkCallback(child, callback, recursive=False) + else: + watch_id = self.notifier._isWatched(dir_path) + if watch_id is None: + log.warning( + f"There is no watch ID for path {dir_path}, this should not happen" + ) + else: + watch_point = self.notifier._watchpoints[watch_id] + if callback not in watch_point.callbacks: + watch_point.callbacks.append(callback) + def watchDir(self, dir_path, callback, mask=DEFAULT_MASK, auto_add=False, recursive=False, **kwargs): + dir_path = str(dir_path) log.info(_("Watching directory {dir_path}").format(dir_path=dir_path)) - callbacks = [lambda __, filepath, mask: callback(self.host, filepath, - inotify.humanReadableMask(mask), **kwargs)] + wrapped_callback = lambda __, filepath, mask: callback( + self.host, filepath, inotify.humanReadableMask(mask), **kwargs) + callbacks = [wrapped_callback] + dir_path = filepath.FilePath(dir_path) self.notifier.watch( - filepath.FilePath(dir_path), mask=mask, autoAdd=auto_add, recursive=recursive, + dir_path, mask=mask, autoAdd=auto_add, recursive=recursive, callbacks=callbacks) + self._checkCallback(dir_path, wrapped_callback, recursive) class LiberviaSession(server.Session):