diff --git a/libervia/backend/core/constants.py b/libervia/backend/core/constants.py index a5546d5c..2c07f6b5 100644 --- a/libervia/backend/core/constants.py +++ b/libervia/backend/core/constants.py @@ -525,6 +525,7 @@ class Const: IGNORE = "ignore" NO_LIMIT = -1 # used in bridge when a integer value is expected DEFAULT_MAX_AGE = 1209600 # default max age of cached files, in seconds + MAX_AGE_PERSISTENT = -1 # keep a cache entry indefinitely STANZA_NAMES = ("iq", "message", "presence") # Stream Hooks diff --git a/libervia/backend/memory/cache.py b/libervia/backend/memory/cache.py index 0e39bbc6..de160c18 100644 --- a/libervia/backend/memory/cache.py +++ b/libervia/backend/memory/cache.py @@ -22,7 +22,7 @@ from pathlib import Path import time from typing import Any -from pydantic import BaseModel, ValidationError +from pydantic import BaseModel, Field, ValidationError from libervia.backend import G from libervia.backend.core import exceptions @@ -42,7 +42,9 @@ class CacheMetadata(BaseModel): uid: str filename: str creation: int - eol: int + eol: int | None = Field( + default=None, description="End of life. If None, entry is kept indefinitely" + ) max_age: int = C.DEFAULT_MAX_AGE original_filename: str | None = None mime_type: str | None = None @@ -95,7 +97,7 @@ class Cache: f"and will be deleted: {cache_data_file!r}." ) to_delete.add(cache_data_file) - elif cache_data.eol < now: + elif cache_data.eol is not None and cache_data.eol < now: log.debug( f"Purging expired cache file {cache_data_file} (expired for " f"{int(time.time() - cache_data.eol)}s)" @@ -156,7 +158,7 @@ class Cache: log.warning(f"Invalid encoding, this is not a cache metadata file.") return None - if cache_data.eol < time.time(): + if cache_data.eol is not None and cache_data.eol < time.time(): log.debug( "removing expired cache (expired for {}s)".format( time.time() - cache_data.eol @@ -164,7 +166,7 @@ class Cache: ) return None - if update_eol: + if update_eol and cache_data.eol is not None: now = int(time.time()) cache_data.last_access = now cache_data.eol = now + cache_data.max_age @@ -236,6 +238,7 @@ class Cache: the cache metadata will have an "eol" (end of life) None to use default value 0 to ignore cache (file will be re-downloaded on each access) + C.MAX_AGE_PERSISTENT to keep the entry in cache indefinitely @param original_filename: if not None, will be used to retrieve file extension and guess mime type, and stored in "original_filename" @return: file object opened in write mode @@ -266,7 +269,7 @@ class Cache: original_filename=original_filename, filename=filename, creation=now, - eol=now + max_age, + eol=None if max_age == C.MAX_AGE_PERSISTENT else now + max_age, ) cache_metadata_file = self.get_path(f"{uid}{CACHE_METADATA_EXT}") diff --git a/libervia/backend/plugins/plugin_xep_0231.py b/libervia/backend/plugins/plugin_xep_0231.py index efa8b39d..5062e34c 100644 --- a/libervia/backend/plugins/plugin_xep_0231.py +++ b/libervia/backend/plugins/plugin_xep_0231.py @@ -194,7 +194,8 @@ class XEP_0231(object): ) data_elt["cid"] = cid data_elt["type"] = metadata["mime_type"] - data_elt["max-age"] = str(int(max(0, metadata["eol"] - time.time()))) + if metadata["eol"] is not None: + data_elt["max-age"] = str(int(max(0, metadata["eol"] - time.time()))) client.send(result_elt) def _get_file(self, peer_jid_s, cid, profile):