From 12c526046f6a750194cf878991be3672cd2bebc8 Mon Sep 17 00:00:00 2001 From: Dirk Alders Date: Sun, 15 Sep 2024 13:24:04 +0200 Subject: [PATCH] Added age as criteria to not use the cached value added --- __init__.py | 64 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/__init__.py b/__init__.py index 5ebacfd..84f1be0 100644 --- a/__init__.py +++ b/__init__.py @@ -24,13 +24,12 @@ caching (Caching Module) """ __DEPENDENCIES__ = [] -import hashlib -import hmac import json import logging import os import pickle import sys +import time try: from config import APP_NAME as ROOT_LOGGER_NAME @@ -81,13 +80,20 @@ class property_cache_pickle(object): """ LOG_PREFIX = 'PickCache:' DATA_VERSION_TAG = '_property_cache_data_version_' + STORAGE_VERSION_TAG = '_storage_version_' UID_TAG = '_property_cache_uid_' + DATA_TAG = '_data_' + AGE_TAG = '_age_' + # + STORAGE_VERSION = 1 - def __init__(self, source_instance, cache_filename, load_all_on_init=False, callback_on_data_storage=None): + def __init__(self, source_instance, cache_filename, load_all_on_init=False, callback_on_data_storage=None, max_age=None, store_none_value=False): self._source_instance = source_instance self._cache_filename = cache_filename self._load_all_on_init = load_all_on_init self._callback_on_data_storage = callback_on_data_storage + self._max_age = max_age + self._store_none_value = store_none_value self._cached_props = None def get(self, key, default=None): @@ -101,14 +107,27 @@ class property_cache_pickle(object): if key in self.keys(): if self._cached_props is None: self._init_cache() - if self._key_filter(key) not in self._cached_props: + if self._max_age is None: + cache_old = False + else: + cache_old = time.time() - self._cached_props[self.AGE_TAG].get(self._key_filter(key), 0) > self._max_age + if cache_old: + logger.debug("The cached value is old, cached value will be ignored") + if self._key_filter(key) not in self._cached_props[self.DATA_TAG] or cache_old: val = self._source_instance.get(key, None) logger.debug("%s Loading property for '%s' from source instance (%s)", self.LOG_PREFIX, key, repr(val)) - self._cached_props[self._key_filter(key)] = val - self._save_cache() + if val or self._store_none_value: + tm = int(time.time()) + logger.debug("Storing value=%s with timestamp=%d to chache", val, tm) + self._cached_props[self.DATA_TAG][self._key_filter(key)] = val + self._cached_props[self.AGE_TAG][self._key_filter(key)] = tm + self._save_cache() + else: + return val else: - logger.debug("%s Providing property for '%s' from cache (%s)", self.LOG_PREFIX, key, repr(self._cached_props.get(self._key_filter(key), default))) - return self._cached_props.get(self._key_filter(key), default) + logger.debug("%s Providing property for '%s' from cache (%s)", self.LOG_PREFIX, + key, repr(self._cached_props[self.DATA_TAG].get(self._key_filter(key), default))) + return self._cached_props[self.DATA_TAG].get(self._key_filter(key), default) else: logger.info("%s Key '%s' is not in cached_keys. Uncached data will be returned.", self.LOG_PREFIX, key) return self._source_instance.get(key, default) @@ -125,17 +144,31 @@ class property_cache_pickle(object): else: return self._cached_props.get(self.DATA_VERSION_TAG, None) + def _storage_version(self): + if self._cached_props is None: + return None + else: + return self._cached_props.get(self.STORAGE_VERSION_TAG, None) + def _init_cache(self): - if not self._load_cache() or self._source_instance.uid() != self._uid() or self._source_instance.data_version() > self._data_version(): - if self._uid() is not None and self._source_instance.uid() != self._uid(): + load_cache = self._load_cache() + uid = self._source_instance.uid() != self._uid() + data_version = self._source_instance.data_version() > self._data_version() + storage_version = self._storage_version() != self.STORAGE_VERSION + # + if not load_cache or uid or data_version or storage_version: + if self._uid() is not None and uid: logger.debug("%s Source uid changed, ignoring previous cache data", self.LOG_PREFIX) - if self._data_version() is not None and self._source_instance.data_version() > self._data_version(): + if self._data_version() is not None and data_version: logger.debug("%s Data version increased, ignoring previous cache data", self.LOG_PREFIX) - self._cached_props = dict() + if storage_version: + logger.debug("%s Storage version changed, ignoring previous cache data", self.LOG_PREFIX) + self._cached_props = {self.AGE_TAG: {}, self.DATA_TAG: {}} if self._load_all_on_init: self._load_source() self._cached_props[self.UID_TAG] = self._source_instance.uid() self._cached_props[self.DATA_VERSION_TAG] = self._source_instance.data_version() + self._cached_props[self.STORAGE_VERSION_TAG] = self.STORAGE_VERSION self._save_cache() def _load_cache(self): @@ -149,13 +182,6 @@ class property_cache_pickle(object): return False def _key_filter(self, key): - if sys.version_info >= (3, 0): - tps = [str] - else: - tps = [str, unicode] - if type(key) in tps: - if key.endswith(self.DATA_VERSION_TAG) or key.endswith(self.UID_TAG): - return '_' + key return key def _load_source(self):