Mercurial > libervia-web
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 |