add short ttl on archiver read
This commit is contained in:
parent
bf1c79577f
commit
cf382f0963
2 changed files with 27 additions and 7 deletions
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue