Browse Source

Added age as criteria to not use the cached value added

master
Dirk Alders 3 months ago
parent
commit
12c526046f
1 changed files with 45 additions and 19 deletions
  1. 45
    19
      __init__.py

+ 45
- 19
__init__.py View File

24
 """
24
 """
25
 __DEPENDENCIES__ = []
25
 __DEPENDENCIES__ = []
26
 
26
 
27
-import hashlib
28
-import hmac
29
 import json
27
 import json
30
 import logging
28
 import logging
31
 import os
29
 import os
32
 import pickle
30
 import pickle
33
 import sys
31
 import sys
32
+import time
34
 
33
 
35
 try:
34
 try:
36
     from config import APP_NAME as ROOT_LOGGER_NAME
35
     from config import APP_NAME as ROOT_LOGGER_NAME
81
     """
80
     """
82
     LOG_PREFIX = 'PickCache:'
81
     LOG_PREFIX = 'PickCache:'
83
     DATA_VERSION_TAG = '_property_cache_data_version_'
82
     DATA_VERSION_TAG = '_property_cache_data_version_'
83
+    STORAGE_VERSION_TAG = '_storage_version_'
84
     UID_TAG = '_property_cache_uid_'
84
     UID_TAG = '_property_cache_uid_'
85
+    DATA_TAG = '_data_'
86
+    AGE_TAG = '_age_'
87
+    #
88
+    STORAGE_VERSION = 1
85
 
89
 
86
-    def __init__(self, source_instance, cache_filename, load_all_on_init=False, callback_on_data_storage=None):
90
+    def __init__(self, source_instance, cache_filename, load_all_on_init=False, callback_on_data_storage=None, max_age=None, store_none_value=False):
87
         self._source_instance = source_instance
91
         self._source_instance = source_instance
88
         self._cache_filename = cache_filename
92
         self._cache_filename = cache_filename
89
         self._load_all_on_init = load_all_on_init
93
         self._load_all_on_init = load_all_on_init
90
         self._callback_on_data_storage = callback_on_data_storage
94
         self._callback_on_data_storage = callback_on_data_storage
95
+        self._max_age = max_age
96
+        self._store_none_value = store_none_value
91
         self._cached_props = None
97
         self._cached_props = None
92
 
98
 
93
     def get(self, key, default=None):
99
     def get(self, key, default=None):
101
         if key in self.keys():
107
         if key in self.keys():
102
             if self._cached_props is None:
108
             if self._cached_props is None:
103
                 self._init_cache()
109
                 self._init_cache()
104
-            if self._key_filter(key) not in self._cached_props:
110
+            if self._max_age is None:
111
+                cache_old = False
112
+            else:
113
+                cache_old = time.time() - self._cached_props[self.AGE_TAG].get(self._key_filter(key), 0) > self._max_age
114
+                if cache_old:
115
+                    logger.debug("The cached value is old, cached value will be ignored")
116
+            if self._key_filter(key) not in self._cached_props[self.DATA_TAG] or cache_old:
105
                 val = self._source_instance.get(key, None)
117
                 val = self._source_instance.get(key, None)
106
                 logger.debug("%s Loading property for '%s' from source instance (%s)", self.LOG_PREFIX, key, repr(val))
118
                 logger.debug("%s Loading property for '%s' from source instance (%s)", self.LOG_PREFIX, key, repr(val))
107
-                self._cached_props[self._key_filter(key)] = val
108
-                self._save_cache()
119
+                if val or self._store_none_value:
120
+                    tm = int(time.time())
121
+                    logger.debug("Storing value=%s with timestamp=%d to chache", val, tm)
122
+                    self._cached_props[self.DATA_TAG][self._key_filter(key)] = val
123
+                    self._cached_props[self.AGE_TAG][self._key_filter(key)] = tm
124
+                    self._save_cache()
125
+                else:
126
+                    return val
109
             else:
127
             else:
110
-                logger.debug("%s Providing property for '%s' from cache (%s)", self.LOG_PREFIX, key, repr(self._cached_props.get(self._key_filter(key), default)))
111
-            return self._cached_props.get(self._key_filter(key), default)
128
+                logger.debug("%s Providing property for '%s' from cache (%s)", self.LOG_PREFIX,
129
+                             key, repr(self._cached_props[self.DATA_TAG].get(self._key_filter(key), default)))
130
+            return self._cached_props[self.DATA_TAG].get(self._key_filter(key), default)
112
         else:
131
         else:
113
             logger.info("%s Key '%s' is not in cached_keys. Uncached data will be returned.", self.LOG_PREFIX, key)
132
             logger.info("%s Key '%s' is not in cached_keys. Uncached data will be returned.", self.LOG_PREFIX, key)
114
             return self._source_instance.get(key, default)
133
             return self._source_instance.get(key, default)
125
         else:
144
         else:
126
             return self._cached_props.get(self.DATA_VERSION_TAG, None)
145
             return self._cached_props.get(self.DATA_VERSION_TAG, None)
127
 
146
 
147
+    def _storage_version(self):
148
+        if self._cached_props is None:
149
+            return None
150
+        else:
151
+            return self._cached_props.get(self.STORAGE_VERSION_TAG, None)
152
+
128
     def _init_cache(self):
153
     def _init_cache(self):
129
-        if not self._load_cache() or self._source_instance.uid() != self._uid() or self._source_instance.data_version() > self._data_version():
130
-            if self._uid() is not None and self._source_instance.uid() != self._uid():
154
+        load_cache = self._load_cache()
155
+        uid = self._source_instance.uid() != self._uid()
156
+        data_version = self._source_instance.data_version() > self._data_version()
157
+        storage_version = self._storage_version() != self.STORAGE_VERSION
158
+        #
159
+        if not load_cache or uid or data_version or storage_version:
160
+            if self._uid() is not None and uid:
131
                 logger.debug("%s Source uid changed, ignoring previous cache data", self.LOG_PREFIX)
161
                 logger.debug("%s Source uid changed, ignoring previous cache data", self.LOG_PREFIX)
132
-            if self._data_version() is not None and self._source_instance.data_version() > self._data_version():
162
+            if self._data_version() is not None and data_version:
133
                 logger.debug("%s Data version increased, ignoring previous cache data", self.LOG_PREFIX)
163
                 logger.debug("%s Data version increased, ignoring previous cache data", self.LOG_PREFIX)
134
-            self._cached_props = dict()
164
+            if storage_version:
165
+                logger.debug("%s Storage version changed, ignoring previous cache data", self.LOG_PREFIX)
166
+            self._cached_props = {self.AGE_TAG: {}, self.DATA_TAG: {}}
135
             if self._load_all_on_init:
167
             if self._load_all_on_init:
136
                 self._load_source()
168
                 self._load_source()
137
             self._cached_props[self.UID_TAG] = self._source_instance.uid()
169
             self._cached_props[self.UID_TAG] = self._source_instance.uid()
138
             self._cached_props[self.DATA_VERSION_TAG] = self._source_instance.data_version()
170
             self._cached_props[self.DATA_VERSION_TAG] = self._source_instance.data_version()
171
+            self._cached_props[self.STORAGE_VERSION_TAG] = self.STORAGE_VERSION
139
             self._save_cache()
172
             self._save_cache()
140
 
173
 
141
     def _load_cache(self):
174
     def _load_cache(self):
149
         return False
182
         return False
150
 
183
 
151
     def _key_filter(self, key):
184
     def _key_filter(self, key):
152
-        if sys.version_info >= (3, 0):
153
-            tps = [str]
154
-        else:
155
-            tps = [str, unicode]
156
-        if type(key) in tps:
157
-            if key.endswith(self.DATA_VERSION_TAG) or key.endswith(self.UID_TAG):
158
-                return '_' + key
159
         return key
185
         return key
160
 
186
 
161
     def _load_source(self):
187
     def _load_source(self):

Loading…
Cancel
Save