add short ttl on archiver read

This commit is contained in:
arabcoders 2025-09-01 17:14:44 +03:00
parent bf1c79577f
commit cf382f0963
2 changed files with 27 additions and 7 deletions

View file

@ -26,6 +26,7 @@ class _Entry:
self.size: int = -1 self.size: int = -1
self.mtime: float = -1.0 self.mtime: float = -1.0
self.loaded: bool = False self.loaded: bool = False
self.last_check: float = 0.0
class Archiver(metaclass=ThreadSafe): class Archiver(metaclass=ThreadSafe):
@ -45,7 +46,8 @@ class Archiver(metaclass=ThreadSafe):
self._cache: dict[str, _Entry] = {} self._cache: dict[str, _Entry] = {}
self._locks: dict[str, threading.RLock] = {} self._locks: dict[str, threading.RLock] = {}
self._global_lock = threading.RLock() self._global_lock = threading.RLock()
self._stats_check: bool = False self._stats_check: bool = True
self._stats_ttl: float = 0.2
self._initialized = True self._initialized = True
@classmethod @classmethod
@ -130,7 +132,13 @@ class Archiver(metaclass=ThreadSafe):
if not self._stats_check: if not self._stats_check:
return entry return entry
if self._stats_ttl > 0:
now = time.monotonic()
if (now - (entry.last_check or 0.0)) < self._stats_ttl:
return entry
st: os.stat_result | None = self._stat(key) st: os.stat_result | None = self._stat(key)
entry.last_check = time.monotonic()
if not st: if not st:
self._cache[key] = _Entry() self._cache[key] = _Entry()
@ -148,6 +156,7 @@ class Archiver(metaclass=ThreadSafe):
entry.size = -1 entry.size = -1
entry.mtime = -1 entry.mtime = -1
entry.loaded = True entry.loaded = True
entry.last_check = time.monotonic()
self._cache[key] = entry self._cache[key] = entry
return entry return entry
@ -178,6 +187,7 @@ class Archiver(metaclass=ThreadSafe):
entry.size = st.st_size entry.size = st.st_size
entry.mtime = st.st_mtime entry.mtime = st.st_mtime
entry.loaded = True entry.loaded = True
entry.last_check = time.monotonic()
self._cache[key] = entry self._cache[key] = entry
return entry return entry
@ -284,6 +294,7 @@ class Archiver(metaclass=ThreadSafe):
st: os.stat_result | None = self._stat(key) st: os.stat_result | None = self._stat(key)
if st: if st:
entry.size, entry.mtime = st.st_size, st.st_mtime entry.size, entry.mtime = st.st_size, st.st_mtime
entry.last_check = time.monotonic()
return True return True
@ -353,12 +364,12 @@ class Archiver(metaclass=ThreadSafe):
st: os.stat_result | None = self._stat(key) st: os.stat_result | None = self._stat(key)
if st: if st:
entry.size, entry.mtime = st.st_size, st.st_mtime entry.size, entry.mtime = st.st_size, st.st_mtime
entry.last_check = time.monotonic()
self._cache[key] = entry self._cache[key] = entry
return True return True
# Global configuration
@classmethod @classmethod
def set_skip_read_stat_checks(cls, skip: bool = True) -> None: def set_skip_read_stat_checks(cls, skip: bool = True) -> None:
""" """
@ -375,3 +386,17 @@ class Archiver(metaclass=ThreadSafe):
inst = cls.get_instance() inst = cls.get_instance()
with inst._global_lock: with inst._global_lock:
inst._stats_check = not skip inst._stats_check = not skip
@classmethod
def set_read_stat_ttl(cls, seconds: float = 0.0) -> None:
"""
Set a short TTL to throttle os.stat checks on reads.
Args:
seconds (float): Minimum time between successive stat() calls per file
when checking for external changes. Use 0 to disable throttling.
"""
inst = cls.get_instance()
with inst._global_lock:
inst._stats_ttl = max(0.0, float(seconds))

View file

@ -1,12 +1,9 @@
import logging
from typing import Any from typing import Any
import yt_dlp import yt_dlp
import app.postprocessors # noqa: F401 import app.postprocessors # noqa: F401
LOG: logging.Logger = logging.getLogger(__name__)
class _ArchiveProxy: class _ArchiveProxy:
""" """
@ -26,7 +23,6 @@ class _ArchiveProxy:
from app.library.Archiver import Archiver from app.library.Archiver import Archiver
status: bool = item in Archiver.get_instance().read(self._file, [item]) status: bool = item in Archiver.get_instance().read(self._file, [item])
LOG.debug(f"ArchiveProxy: '{item}' in '{self._file}': {'yes' if status else 'no'}.")
return status return status
except Exception: except Exception:
return False return False
@ -39,7 +35,6 @@ class _ArchiveProxy:
from app.library.Archiver import Archiver from app.library.Archiver import Archiver
status: bool = Archiver.get_instance().add(self._file, [item]) status: bool = Archiver.get_instance().add(self._file, [item])
LOG.debug(f"ArchiveProxy: Added '{item}' to '{self._file}': {'yes' if status else 'no'}.")
return status return status
except Exception: except Exception:
return False return False