comparison libervia/server/server.py @ 1251:a1606e2a92eb

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.
author Goffi <goffi@goffi.org>
date Wed, 29 Apr 2020 14:54:33 +0200
parents aaf28d45ae67
children 6d49fae517ba
comparison
equal deleted inserted replaced
1250:821b6ce57f99 1251:a1606e2a92eb
88 if self._notifier == None: 88 if self._notifier == None:
89 notifier = self.__class__._notifier = inotify.INotify() 89 notifier = self.__class__._notifier = inotify.INotify()
90 notifier.startReading() 90 notifier.startReading()
91 return self._notifier 91 return self._notifier
92 92
93 def _checkCallback(self, dir_path, callback, recursive):
94 # Twisted doesn't add callback if a watcher was already set on a path
95 # but in dev mode Libervia watches whole sites + internal path can be watched
96 # by tasks, so several callbacks must be called on some paths.
97 # This method check that the new callback is indeed present in the desired path
98 # and add it otherwise.
99 # FIXME: this should probably be fixed upstream
100 if recursive:
101 for child in dir_path.walk():
102 if child.isdir():
103 self._checkCallback(child, callback, recursive=False)
104 else:
105 watch_id = self.notifier._isWatched(dir_path)
106 if watch_id is None:
107 log.warning(
108 f"There is no watch ID for path {dir_path}, this should not happen"
109 )
110 else:
111 watch_point = self.notifier._watchpoints[watch_id]
112 if callback not in watch_point.callbacks:
113 watch_point.callbacks.append(callback)
114
93 def watchDir(self, dir_path, callback, mask=DEFAULT_MASK, auto_add=False, 115 def watchDir(self, dir_path, callback, mask=DEFAULT_MASK, auto_add=False,
94 recursive=False, **kwargs): 116 recursive=False, **kwargs):
117 dir_path = str(dir_path)
95 log.info(_("Watching directory {dir_path}").format(dir_path=dir_path)) 118 log.info(_("Watching directory {dir_path}").format(dir_path=dir_path))
96 callbacks = [lambda __, filepath, mask: callback(self.host, filepath, 119 wrapped_callback = lambda __, filepath, mask: callback(
97 inotify.humanReadableMask(mask), **kwargs)] 120 self.host, filepath, inotify.humanReadableMask(mask), **kwargs)
121 callbacks = [wrapped_callback]
122 dir_path = filepath.FilePath(dir_path)
98 self.notifier.watch( 123 self.notifier.watch(
99 filepath.FilePath(dir_path), mask=mask, autoAdd=auto_add, recursive=recursive, 124 dir_path, mask=mask, autoAdd=auto_add, recursive=recursive,
100 callbacks=callbacks) 125 callbacks=callbacks)
126 self._checkCallback(dir_path, wrapped_callback, recursive)
101 127
102 128
103 class LiberviaSession(server.Session): 129 class LiberviaSession(server.Session):
104 sessionTimeout = C.SESSION_TIMEOUT 130 sessionTimeout = C.SESSION_TIMEOUT
105 131