file_manager: bundle inotify delete events
When a directory is deleted this attempts to suppress delete events for all children. Clients only need to be notified of the parent node, as its deletion implies all children have been deleted. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
db0eb8f22b
commit
bb00825cd2
|
@ -614,15 +614,16 @@ class INotifyHandler:
|
||||||
self.watches[new_path] = wd
|
self.watches[new_path] = wd
|
||||||
self.watched_dirs[wd] = (new_root, new_path)
|
self.watched_dirs[wd] = (new_root, new_path)
|
||||||
|
|
||||||
def _process_deleted_files(self, dir_path):
|
def _process_deleted_items(self, dir_path):
|
||||||
if dir_path not in self.pending_delete_events:
|
if dir_path not in self.pending_delete_events:
|
||||||
return
|
return
|
||||||
root, files, hdl = self.pending_delete_events.pop(dir_path)
|
root, items, hdl = self.pending_delete_events.pop(dir_path)
|
||||||
for fname in files:
|
for (item_name, isdir) in items:
|
||||||
file_path = os.path.join(dir_path, fname)
|
item_path = os.path.join(dir_path, item_name)
|
||||||
self._clear_metadata(root, file_path)
|
item_type = "dir" if isdir else "file"
|
||||||
|
self._clear_metadata(root, item_path, isdir)
|
||||||
self._notify_filelist_changed(
|
self._notify_filelist_changed(
|
||||||
"delete_file", root, file_path)
|
f"delete_{item_type}", root, item_path)
|
||||||
|
|
||||||
def _remove_stale_cookie(self, cookie):
|
def _remove_stale_cookie(self, cookie):
|
||||||
pending_evt = self.pending_move_events.pop(cookie, None)
|
pending_evt = self.pending_move_events.pop(cookie, None)
|
||||||
|
@ -729,6 +730,24 @@ class INotifyHandler:
|
||||||
else:
|
else:
|
||||||
self._process_file_event(evt, root, child_path)
|
self._process_file_event(evt, root, child_path)
|
||||||
|
|
||||||
|
def _schedule_delete_event(self, root, item_path, is_dir):
|
||||||
|
if is_dir:
|
||||||
|
self.remove_watch(item_path, need_low_level_rm=False)
|
||||||
|
# Remove pending delete events for children if they exist
|
||||||
|
pending_evt = self.pending_delete_events.pop(item_path, None)
|
||||||
|
if pending_evt is not None:
|
||||||
|
delete_hdl = pending_evt[2]
|
||||||
|
self.ioloop.remove_timeout(delete_hdl)
|
||||||
|
parent_path, item_name = os.path.split(item_path)
|
||||||
|
items = set()
|
||||||
|
if parent_path in self.pending_delete_events:
|
||||||
|
root, items, delete_hdl = self.pending_delete_events[parent_path]
|
||||||
|
self.ioloop.remove_timeout(delete_hdl)
|
||||||
|
items.add((item_name, is_dir))
|
||||||
|
delete_hdl = self.ioloop.call_later(
|
||||||
|
INOTIFY_DELETE_TIME, self._process_deleted_items, parent_path)
|
||||||
|
self.pending_delete_events[parent_path] = (root, items, delete_hdl)
|
||||||
|
|
||||||
def _process_dir_event(self, evt, root, child_path):
|
def _process_dir_event(self, evt, root, child_path):
|
||||||
if evt.name and evt.name[0] == ".":
|
if evt.name and evt.name[0] == ".":
|
||||||
# ignore changes to the hidden directories
|
# ignore changes to the hidden directories
|
||||||
|
@ -740,14 +759,7 @@ class INotifyHandler:
|
||||||
"create_dir", root, child_path)
|
"create_dir", root, child_path)
|
||||||
elif evt.mask & iFlags.DELETE:
|
elif evt.mask & iFlags.DELETE:
|
||||||
logging.debug(f"Inotify directory delete: {root}, {evt.name}")
|
logging.debug(f"Inotify directory delete: {root}, {evt.name}")
|
||||||
self.remove_watch(child_path, need_low_level_rm=False)
|
self._schedule_delete_event(root, child_path, True)
|
||||||
pending_evt = self.pending_delete_events.pop(child_path, None)
|
|
||||||
if pending_evt is not None:
|
|
||||||
delete_hdl = pending_evt[2]
|
|
||||||
self.ioloop.remove_timeout(delete_hdl)
|
|
||||||
self._clear_metadata(root, child_path, True)
|
|
||||||
self._notify_filelist_changed(
|
|
||||||
"delete_dir", root, child_path)
|
|
||||||
elif evt.mask & iFlags.MOVED_FROM:
|
elif evt.mask & iFlags.MOVED_FROM:
|
||||||
logging.debug(f"Inotify directory move from: {root}, {evt.name}")
|
logging.debug(f"Inotify directory move from: {root}, {evt.name}")
|
||||||
hdl = self.ioloop.call_later(
|
hdl = self.ioloop.call_later(
|
||||||
|
@ -791,19 +803,11 @@ class INotifyHandler:
|
||||||
if root == "gcodes" and ext == ".ufp":
|
if root == "gcodes" and ext == ".ufp":
|
||||||
# Don't notify deleted ufp files
|
# Don't notify deleted ufp files
|
||||||
return
|
return
|
||||||
dir_path, fname = os.path.split(child_path)
|
self._schedule_delete_event(root, child_path, False)
|
||||||
files = set()
|
|
||||||
if dir_path in self.pending_delete_events:
|
|
||||||
root, files, delete_hdl = self.pending_delete_events[dir_path]
|
|
||||||
self.ioloop.remove_timeout(delete_hdl)
|
|
||||||
files.add(fname)
|
|
||||||
delete_hdl = self.ioloop.call_later(
|
|
||||||
INOTIFY_MOVE_TIME, self._process_deleted_files, dir_path)
|
|
||||||
self.pending_delete_events[dir_path] = (root, files, delete_hdl)
|
|
||||||
elif evt.mask & iFlags.MOVED_FROM:
|
elif evt.mask & iFlags.MOVED_FROM:
|
||||||
logging.debug(f"Inotify file move from: {root}, {evt.name}")
|
logging.debug(f"Inotify file move from: {root}, {evt.name}")
|
||||||
hdl = self.ioloop.call_later(
|
hdl = self.ioloop.call_later(
|
||||||
INOTIFY_DELETE_TIME, self._remove_stale_cookie, evt.cookie)
|
INOTIFY_MOVE_TIME, self._remove_stale_cookie, evt.cookie)
|
||||||
self.pending_move_events[evt.cookie] = (
|
self.pending_move_events[evt.cookie] = (
|
||||||
root, child_path, hdl, False)
|
root, child_path, hdl, False)
|
||||||
self._clear_metadata(root, child_path)
|
self._clear_metadata(root, child_path)
|
||||||
|
|
Loading…
Reference in New Issue