Further bugfixes. Increase full update interval to 5 minutes.

This commit is contained in:
Leo Vasanko 2023-11-20 19:22:49 +00:00
parent dbb06e111c
commit a49dd2f111
2 changed files with 29 additions and 29 deletions

View File

@ -120,9 +120,12 @@ class FileEntry(msgspec.Struct, array_like=True, frozen=True):
size: int size: int
isfile: int isfile: int
def __repr__(self): def __str__(self):
return self.key or "FileEntry()" return self.key or "FileEntry()"
def __repr__(self):
return f"{self.name} ({self.size}, {self.mtime})"
class Update(msgspec.Struct, array_like=True): class Update(msgspec.Struct, array_like=True):
... ...

View File

@ -24,7 +24,7 @@ class State:
def __init__(self): def __init__(self):
self.lock = threading.RLock() self.lock = threading.RLock()
self._space = Space(0, 0, 0, 0) self._space = Space(0, 0, 0, 0)
self._listing: list[FileEntry] = [] self.root: list[FileEntry] = []
@property @property
def space(self): def space(self):
@ -36,16 +36,6 @@ class State:
with self.lock: with self.lock:
self._space = space self._space = space
@property
def root(self) -> list[FileEntry]:
with self.lock:
return self._listing[:]
@root.setter
def root(self, listing: list[FileEntry]):
with self.lock:
self._listing = listing
def treeiter(rootmod): def treeiter(rootmod):
relpath = PurePosixPath() relpath = PurePosixPath()
@ -136,7 +126,7 @@ def walk(rel: PurePosixPath, stat: stat_result | None = None) -> list[FileEntry]
if isfile: if isfile:
return [entry] return [entry]
# Walk all entries of the directory # Walk all entries of the directory
ret = [entry] ret: list[FileEntry] = [...] # type: ignore
li = [] li = []
for f in path.iterdir(): for f in path.iterdir():
if quit.is_set(): if quit.is_set():
@ -155,15 +145,15 @@ def walk(rel: PurePosixPath, stat: stat_result | None = None) -> list[FileEntry]
sub = walk(rel / name, stat=s) sub = walk(rel / name, stat=s)
child = sub[0] child = sub[0]
entry = FileEntry( entry = FileEntry(
entry.level, level=entry.level,
entry.name, name=entry.name,
entry.key, key=entry.key,
entry.size + child.size, size=entry.size + child.size,
max(entry.mtime, child.mtime), mtime=max(entry.mtime, child.mtime),
entry.isfile, isfile=entry.isfile,
) )
ret[0] = entry
ret.extend(sub) ret.extend(sub)
ret[0] = entry
except FileNotFoundError: except FileNotFoundError:
pass # Things may be rapidly in motion pass # Things may be rapidly in motion
except OSError as e: except OSError as e:
@ -175,12 +165,13 @@ def walk(rel: PurePosixPath, stat: stat_result | None = None) -> list[FileEntry]
def update_root(loop): def update_root(loop):
"""Full filesystem scan""" """Full filesystem scan"""
new = walk(PurePosixPath())
with state.lock:
old = state.root old = state.root
new = walk(PurePosixPath())
if old != new: if old != new:
update = format_update(old, new)
with state.lock:
broadcast(update, loop)
state.root = new state.root = new
broadcast(format_update(old, new), loop)
def update_path(rootmod: list[FileEntry], relpath: PurePosixPath, loop): def update_path(rootmod: list[FileEntry], relpath: PurePosixPath, loop):
@ -323,7 +314,7 @@ def watcher_inotify(loop):
update_root(loop) update_root(loop)
t1 = time.perf_counter() t1 = time.perf_counter()
logger.debug(f"Root update took {t1 - t0:.1f}s") logger.debug(f"Root update took {t1 - t0:.1f}s")
trefresh = time.monotonic() + 30.0 trefresh = time.monotonic() + 300.0
tspace = time.monotonic() + 5.0 tspace = time.monotonic() + 5.0
# Watch for changes (frequent wakeups needed for quiting) # Watch for changes (frequent wakeups needed for quiting)
while not quit.is_set(): while not quit.is_set():
@ -336,11 +327,12 @@ def watcher_inotify(loop):
tspace = time.monotonic() + 5.0 tspace = time.monotonic() + 5.0
update_space(loop) update_space(loop)
# Inotify events, update the tree # Inotify events, update the tree
events = list(i.event_gen(yield_nones=False, timeout_s=0.1))
dirty = False dirty = False
rootmod = list(state.root) rootmod = state.root[:]
for event in events: for event in i.event_gen(yield_nones=False, timeout_s=0.1):
assert event assert event
if quit.is_set():
return
interesting = any(f in modified_flags for f in event[1]) interesting = any(f in modified_flags for f in event[1])
if event[2] == rootpath.as_posix() and event[3] == "zzz": if event[2] == rootpath.as_posix() and event[3] == "zzz":
logger.debug(f"Watch: {interesting=} {event=}") logger.debug(f"Watch: {interesting=} {event=}")
@ -351,7 +343,12 @@ def watcher_inotify(loop):
update_path(rootmod, path.relative_to(rootpath), loop) update_path(rootmod, path.relative_to(rootpath), loop)
t1 = time.perf_counter() t1 = time.perf_counter()
logger.debug(f"Watch: Update {event[3]} took {t1 - t0:.1f}s") logger.debug(f"Watch: Update {event[3]} took {t1 - t0:.1f}s")
if not dirty:
t = time.monotonic()
dirty = True dirty = True
# Wait a maximum of 0.5s to push the updates
if dirty and time.monotonic() >= t + 0.5:
break
if dirty and state.root != rootmod: if dirty and state.root != rootmod:
t0 = time.perf_counter() t0 = time.perf_counter()
update = format_update(state.root, rootmod) update = format_update(state.root, rootmod)