Browse Source

Interface improvement for cached object (inkl. example adaption)

master
Dirk Alders 3 months ago
parent
commit
529f4100b6
3 changed files with 108 additions and 126 deletions
  1. 26
    6
      __init__.py
  2. 41
    60
      _examples_/property_cache_json.py
  3. 41
    60
      _examples_/property_cache_pickle.py

+ 26
- 6
__init__.py View File

28
 import logging
28
 import logging
29
 import os
29
 import os
30
 import pickle
30
 import pickle
31
-import sys
32
 import time
31
 import time
33
 
32
 
34
 try:
33
 try:
53
     :param cache_filename: File name, where the properties are stored as cache
52
     :param cache_filename: File name, where the properties are stored as cache
54
     :type cache_filename: str
53
     :type cache_filename: str
55
     :param load_all_on_init: Optionally init behaviour control parameter. True will load all available properties from source on init, False not.
54
     :param load_all_on_init: Optionally init behaviour control parameter. True will load all available properties from source on init, False not.
55
+    :param max_age: The maximum age of the cache object, after that time the source will be used for getting information.
56
+    :type max_age: int
57
+    :param store_on_get: Parameter to enable / disable cache storage on get. If you disble data storage, you need to update and store the cache manually
56
 
58
 
57
     .. note:: source_instance needs to have at least the following methods: uid(), keys(), data_version(), get()
59
     .. note:: source_instance needs to have at least the following methods: uid(), keys(), data_version(), get()
58
 
60
 
94
         self._callback_on_data_storage = callback_on_data_storage
96
         self._callback_on_data_storage = callback_on_data_storage
95
         self._max_age = max_age
97
         self._max_age = max_age
96
         self._store_on_get = store_on_get
98
         self._store_on_get = store_on_get
99
+        #
100
+        self._source_get_keys = []
97
         self._cached_props = None
101
         self._cached_props = None
98
 
102
 
99
     def get(self, key, default=None):
103
     def get(self, key, default=None):
104
         :param default: value to be returned, if key does not exists.
108
         :param default: value to be returned, if key does not exists.
105
         :returns: value for a given key or default value.
109
         :returns: value for a given key or default value.
106
         """
110
         """
107
-        if key in self.keys():
111
+        if key in self.keys() and key not in self._source_get_keys:
108
             if self._cached_props is None:
112
             if self._cached_props is None:
109
                 self._init_cache()
113
                 self._init_cache()
110
             if self._max_age is None:
114
             if self._max_age is None:
198
     def _load_source(self):
202
     def _load_source(self):
199
         if self._cached_props is None:
203
         if self._cached_props is None:
200
             self._init_cache()
204
             self._init_cache()
201
-        logger.debug('%s Loading all data from source - %s', self.LOG_PREFIX, repr(self._source_instance.keys()))
202
-        for key in self._source_instance.keys():
203
-            self._cached_props[self.DATA_TAG][self._key_filter(key)] = self._source_instance.get(key)
204
-            self._cached_props[self.AGE_TAG][self._key_filter(key)] = int(time.time())
205
+        logger.debug('%s Loading all data from source - %s', self.LOG_PREFIX, repr(self.keys()))
206
+        for key in self.keys():
207
+            if key not in self._source_get_keys:
208
+                self._cached_props[self.DATA_TAG][self._key_filter(key)] = self._source_instance.get(key)
209
+                self._cached_props[self.AGE_TAG][self._key_filter(key)] = int(time.time())
205
 
210
 
206
     def _save_cache(self):
211
     def _save_cache(self):
207
         with open(self._cache_filename, 'wb') as fh:
212
         with open(self._cache_filename, 'wb') as fh:
216
         else:
221
         else:
217
             return self._cached_props.get(self.UID_TAG, None)
222
             return self._cached_props.get(self.UID_TAG, None)
218
 
223
 
224
+    def add_source_get_keys(self, keys):
225
+        if type(keys) in [list, tuple]:
226
+            self._source_get_keys.extend(keys)
227
+        else:
228
+            self._source_get_keys.append(keys)
229
+
230
+    def __getattribute__(self, name):
231
+        try:
232
+            return super().__getattribute__(name)
233
+        except AttributeError:
234
+            return getattr(self._source_instance, name)
235
+
219
 
236
 
220
 class property_cache_json(property_cache_pickle):
237
 class property_cache_json(property_cache_pickle):
221
     """
238
     """
226
     :param cache_filename: File name, where the properties are stored as cache
243
     :param cache_filename: File name, where the properties are stored as cache
227
     :type cache_filename: str
244
     :type cache_filename: str
228
     :param load_all_on_init: Optionally init behaviour control parameter. True will load all available properties from source on init, False not.
245
     :param load_all_on_init: Optionally init behaviour control parameter. True will load all available properties from source on init, False not.
246
+    :param max_age: The maximum age of the cache object, after that time the source will be used for getting information.
247
+    :type max_age: int
248
+    :param store_on_get: Parameter to enable / disable cache storage on get. If you disble data storage, you need to update and store the cache manually
229
 
249
 
230
     .. warning::
250
     .. warning::
231
         * This class uses json. You should **only** use keys of type string!
251
         * This class uses json. You should **only** use keys of type string!

+ 41
- 60
_examples_/property_cache_json.py View File

2
 # -*- coding: UTF-8 -*-
2
 # -*- coding: UTF-8 -*-
3
 
3
 
4
 import sys
4
 import sys
5
-import time
6
 sys.path.append('../..')
5
 sys.path.append('../..')
7
-
8
-import caching
9
 import report
6
 import report
7
+import caching
8
+import time
10
 
9
 
11
 
10
 
12
 report.stdoutLoggingConfigure(log_name_lvl=[('root', 'DEBUG'), ])
11
 report.stdoutLoggingConfigure(log_name_lvl=[('root', 'DEBUG'), ])
13
 
12
 
14
 
13
 
15
 class test_slow_data(object):
14
 class test_slow_data(object):
16
-    _ONE = '1'
17
-    _TWO = '2'
18
-    _THREE = '_property_cache_data_version_'
19
-    _FOUR = '_property_cache_uid_'
20
-    _FIVE = '__property_cache_uid_'
21
-    KEYS = [_ONE, _TWO, _THREE, _FOUR, _FIVE]
22
-    VERS = 0.1
15
+    DATA_VERSION = 0.1
16
+    KEY_ONE = '1'
17
+    KEY_TWO = '2'
18
+    KEY_THREE = 'three'
19
+    KEY_FOUR = 'four'
20
+    KEY_FIVE = 'five'
21
+    KEYS = [KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR, KEY_FIVE]
23
 
22
 
24
     def data_version(self):
23
     def data_version(self):
25
-        return self.VERS
26
-
27
-    def one(self):
28
-        return self.get(self._ONE)
29
-
30
-    def two(self):
31
-        return self.get(self._TWO)
32
-
33
-    def three(self):
34
-        return self.get(self._THREE)
35
-
36
-    def four(self):
37
-        return self.get(self._FOUR)
38
-
39
-    def five(self):
40
-        return self.get(self._FIVE)
24
+        return self.DATA_VERSION
41
 
25
 
42
     def get(self, key, default=None):
26
     def get(self, key, default=None):
43
-        def print_n_sleep(k):
44
-            sys.stdout.write('slow get executed for %s\n' % k)
45
-            time.sleep(3)
46
-        if key == self._ONE:
47
-            print_n_sleep(key)
48
-            return 'one'
49
-        if key == self._TWO:
50
-            print_n_sleep(key)
51
-            return 'two'
52
-        if key == self._THREE:
53
-            print_n_sleep(key)
54
-            return 'three'
55
-        if key == self._FOUR:
56
-            print_n_sleep(key)
57
-            return 'four'
58
-        if key == self._FIVE:
59
-            print_n_sleep(key)
60
-            return 'five'
61
-        return default
27
+        try:
28
+            return getattr(self, f'__{key}__')()
29
+        except AttributeError:
30
+            return default
62
 
31
 
63
     def keys(self):
32
     def keys(self):
64
         return self.KEYS
33
         return self.KEYS
66
     def uid(self):
35
     def uid(self):
67
         return None
36
         return None
68
 
37
 
38
+    def print_n_sleep(self, k):
39
+        sys.stdout.write('slow get executed for %s\n' % k)
40
+        time.sleep(3)
69
 
41
 
70
-class tsd_cache_json(test_slow_data):
71
-    def __init__(self, *args, **kwargs):
72
-        test_slow_data.__init__(self, *args, **kwargs)
73
-        self._cached_data = caching.property_cache_json(test_slow_data(*args, **kwargs), 'cache.json', load_all_on_init=False)
42
+    def __1__(self):
43
+        self.print_n_sleep("__1__")
44
+        return 'one'
74
 
45
 
75
-    def two(self):
76
-        return test_slow_data.get(self, self._TWO)
46
+    def __2__(self):
47
+        self.print_n_sleep("__2__")
48
+        return 'two'
49
+
50
+    def __three__(self):
51
+        self.print_n_sleep("__three__")
52
+        return 'three'
53
+
54
+    def __four__(self):
55
+        self.print_n_sleep("__four__")
56
+        return 'four'
57
+
58
+    def __five__(self):
59
+        self.print_n_sleep("__five__")
60
+        return 'five'
77
 
61
 
78
-    def get(self, key, default=None):
79
-        return self._cached_data.get(key, default)
80
 
62
 
63
+if __name__ == "__main__":
64
+    data = caching.property_cache_json(test_slow_data(), 'cache.json')
65
+    data.add_source_get_keys(data.KEY_THREE)
66
+    print('Testing property_cache (json):\\n--------------------------------')
67
+    for key in data.keys():
68
+        print(data.get(key))
81
 
69
 
82
-data = tsd_cache_json()
83
-print('Testing property_cache (json):\\n--------------------------------')
84
-print(data.one())
85
-print(data.two())
86
-print(data.three())
87
-print(data.four())
88
-print(data.five())

+ 41
- 60
_examples_/property_cache_pickle.py View File

2
 # -*- coding: UTF-8 -*-
2
 # -*- coding: UTF-8 -*-
3
 
3
 
4
 import sys
4
 import sys
5
-import time
6
 sys.path.append('../..')
5
 sys.path.append('../..')
7
-
8
-import caching
9
 import report
6
 import report
7
+import caching
8
+import time
10
 
9
 
11
 
10
 
12
 report.stdoutLoggingConfigure(log_name_lvl=[('root', 'DEBUG'), ])
11
 report.stdoutLoggingConfigure(log_name_lvl=[('root', 'DEBUG'), ])
13
 
12
 
14
 
13
 
15
 class test_slow_data(object):
14
 class test_slow_data(object):
16
-    _ONE = '1'
17
-    _TWO = '2'
18
-    _THREE = '_property_cache_data_version_'
19
-    _FOUR = '_property_cache_uid_'
20
-    _FIVE = '__property_cache_uid_'
21
-    KEYS = [_ONE, _TWO, _THREE, _FOUR, _FIVE]
22
-    VERS = 0.1
15
+    DATA_VERSION = 0.1
16
+    KEY_ONE = '1'
17
+    KEY_TWO = '2'
18
+    KEY_THREE = 'three'
19
+    KEY_FOUR = 'four'
20
+    KEY_FIVE = 'five'
21
+    KEYS = [KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR, KEY_FIVE]
23
 
22
 
24
     def data_version(self):
23
     def data_version(self):
25
-        return self.VERS
26
-
27
-    def one(self):
28
-        return self.get(self._ONE)
29
-
30
-    def two(self):
31
-        return self.get(self._TWO)
32
-
33
-    def three(self):
34
-        return self.get(self._THREE)
35
-
36
-    def four(self):
37
-        return self.get(self._FOUR)
38
-
39
-    def five(self):
40
-        return self.get(self._FIVE)
24
+        return self.DATA_VERSION
41
 
25
 
42
     def get(self, key, default=None):
26
     def get(self, key, default=None):
43
-        def print_n_sleep(k):
44
-            sys.stdout.write('slow get executed for %s\n' % k)
45
-            time.sleep(3)
46
-        if key == self._ONE:
47
-            print_n_sleep(key)
48
-            return 'one'
49
-        if key == self._TWO:
50
-            print_n_sleep(key)
51
-            return 'two'
52
-        if key == self._THREE:
53
-            print_n_sleep(key)
54
-            return 'three'
55
-        if key == self._FOUR:
56
-            print_n_sleep(key)
57
-            return 'four'
58
-        if key == self._FIVE:
59
-            print_n_sleep(key)
60
-            return 'five'
61
-        return default
27
+        try:
28
+            return getattr(self, f'__{key}__')()
29
+        except AttributeError:
30
+            return default
62
 
31
 
63
     def keys(self):
32
     def keys(self):
64
         return self.KEYS
33
         return self.KEYS
66
     def uid(self):
35
     def uid(self):
67
         return None
36
         return None
68
 
37
 
38
+    def print_n_sleep(self, k):
39
+        sys.stdout.write('slow get executed for %s\n' % k)
40
+        time.sleep(3)
69
 
41
 
70
-class tsd_cache_pickle(test_slow_data):
71
-    def __init__(self, *args, **kwargs):
72
-        test_slow_data.__init__(self, *args, **kwargs)
73
-        self._cached_data = caching.property_cache_pickle(test_slow_data(*args, **kwargs), 'cache.pickle', load_all_on_init=False)
42
+    def __1__(self):
43
+        self.print_n_sleep("__1__")
44
+        return 'one'
74
 
45
 
75
-    def two(self):
76
-        return test_slow_data.get(self, self._TWO)
46
+    def __2__(self):
47
+        self.print_n_sleep("__2__")
48
+        return 'two'
49
+
50
+    def __three__(self):
51
+        self.print_n_sleep("__three__")
52
+        return 'three'
53
+
54
+    def __four__(self):
55
+        self.print_n_sleep("__four__")
56
+        return 'four'
57
+
58
+    def __five__(self):
59
+        self.print_n_sleep("__five__")
60
+        return 'five'
77
 
61
 
78
-    def get(self, key, default=None):
79
-        return self._cached_data.get(key, default)
80
 
62
 
63
+if __name__ == "__main__":
64
+    data = caching.property_cache_pickle(test_slow_data(), 'cache.pickle')
65
+    data.add_source_get_keys(data.KEY_THREE)
66
+    print('Testing property_cache (pickle):\\n--------------------------------')
67
+    for key in data.keys():
68
+        print(data.get(key))
81
 
69
 
82
-data = tsd_cache_pickle()
83
-print('Testing property_cache (pickle):\\n--------------------------------')
84
-print(data.one())
85
-print(data.two())
86
-print(data.three())
87
-print(data.four())
88
-print(data.five())

Loading…
Cancel
Save