21541: Code cleanup and additional memory usage improvements
authorPeter Amstutz <peter.amstutz@curii.com>
Mon, 25 Mar 2024 18:19:32 +0000 (14:19 -0400)
committerPeter Amstutz <peter.amstutz@curii.com>
Wed, 27 Mar 2024 20:52:15 +0000 (16:52 -0400)
commitbf4193eeaa390cec08bbb8333a53fbc89edfd7f3
tree7fad1bf01957915164b7c98bff2a6befef7fe16c
parent6dfef004d33b147cbe80bbb5ecc6922ac25f156d
21541: Code cleanup and additional memory usage improvements

* Add slots to major Directory classes

* Disconnect FuseArvadosFile from ArvadosFile to reduce cyclic
references.

* Clean up _remove_inode loop and use dataclasses for the inode
operations.

* Now calls del_entry on collection_record_file and project_object_file.

It looks like collection_record_file was holding a reference to the
Collection object (and was remaining in the inodes table) even when
CollectionDirectory was cleared.  I believe this is the memory leak I
have been looking for.

* Remove the "dead" flag and set parent_inode to None instead.  This
clarifies the behavior that directory entries keep their (numeric)
inodes until they are detached from the directory which may have
contributed to infrequent "file not found" errors.

* Adjust cache behavior to only hold objects that are cache-eligible
and have non-zero cache_size.  This avoids filling the cache with
entries that are just going to be skipped over.

Overall: Memory usage is mostly stable but does tend to creep up over
time.  My best guess is that this is forced because we need to keep
inodes in RAM as long as the kernel maintains a reference to them, so
with multiple processes accessing different filesystem locations, this
is simply RAM required for the working set.

I'm also cautiously optimistic that issues I observed with performance
slowing down with long-lived processes are improved (e.g. fixing
memory leaks means no more unbounded growth of cache_entries, which
means no more time wasted iterating over huge lists).

Arvados-DCO-1.1-Signed-off-by: Peter Amstutz <peter.amstutz@curii.com>
services/fuse/arvados_fuse/__init__.py
services/fuse/arvados_fuse/fresh.py
services/fuse/arvados_fuse/fusedir.py
services/fuse/arvados_fuse/fusefile.py
services/fuse/tests/mount_test_base.py
services/fuse/tests/test_inodes.py