Show More
@@ -58,12 +58,12 b" CLEAR_DELETE = 'delete'" | |||||
58 | CLEAR_INVALIDATE = 'invalidate' |
|
58 | CLEAR_INVALIDATE = 'invalidate' | |
59 |
|
59 | |||
60 |
|
60 | |||
61 |
def async_creation_runner(cache, |
|
61 | def async_creation_runner(cache, cache_key, creator, mutex): | |
62 |
|
62 | |||
63 | def runner(): |
|
63 | def runner(): | |
64 | try: |
|
64 | try: | |
65 | value = creator() |
|
65 | value = creator() | |
66 |
cache.set( |
|
66 | cache.set(cache_key, value) | |
67 | finally: |
|
67 | finally: | |
68 | mutex.release() |
|
68 | mutex.release() | |
69 |
|
69 |
@@ -73,10 +73,20 b' class LRUMemoryBackend(memory_backend.Me' | |||||
73 | # we don't care if key isn't there at deletion |
|
73 | # we don't care if key isn't there at deletion | |
74 | pass |
|
74 | pass | |
75 |
|
75 | |||
|
76 | def list_keys(self, prefix): | |||
|
77 | return list(self._cache.keys()) | |||
|
78 | ||||
76 | def delete_multi(self, keys): |
|
79 | def delete_multi(self, keys): | |
77 | for key in keys: |
|
80 | for key in keys: | |
78 | self.delete(key) |
|
81 | self.delete(key) | |
79 |
|
82 | |||
|
83 | def delete_multi_by_prefix(self, prefix): | |||
|
84 | cache_keys = self.list_keys(prefix=prefix) | |||
|
85 | num_affected_keys = len(cache_keys) | |||
|
86 | if num_affected_keys: | |||
|
87 | self.delete_multi(cache_keys) | |||
|
88 | return num_affected_keys | |||
|
89 | ||||
80 |
|
90 | |||
81 | class PickleSerializer: |
|
91 | class PickleSerializer: | |
82 | serializer: None | Serializer = staticmethod( # type: ignore |
|
92 | serializer: None | Serializer = staticmethod( # type: ignore | |
@@ -146,6 +156,13 b' class FileNamespaceBackend(PickleSeriali' | |||||
146 | log.error('Failed to fetch DBM keys from DB: %s', self.get_store()) |
|
156 | log.error('Failed to fetch DBM keys from DB: %s', self.get_store()) | |
147 | raise |
|
157 | raise | |
148 |
|
158 | |||
|
159 | def delete_multi_by_prefix(self, prefix): | |||
|
160 | cache_keys = self.list_keys(prefix=prefix) | |||
|
161 | num_affected_keys = len(cache_keys) | |||
|
162 | if num_affected_keys: | |||
|
163 | self.delete_multi(cache_keys) | |||
|
164 | return num_affected_keys | |||
|
165 | ||||
149 | def get_store(self): |
|
166 | def get_store(self): | |
150 | return self.filename |
|
167 | return self.filename | |
151 |
|
168 | |||
@@ -195,6 +212,25 b' class BaseRedisBackend(redis_backend.Red' | |||||
195 | prefix = self._get_keys_pattern(prefix) |
|
212 | prefix = self._get_keys_pattern(prefix) | |
196 | return self.reader_client.keys(prefix) |
|
213 | return self.reader_client.keys(prefix) | |
197 |
|
214 | |||
|
215 | def delete_multi_by_prefix(self, prefix, use_lua=False): | |||
|
216 | if use_lua: | |||
|
217 | # high efficient LUA script to delete ALL keys by prefix... | |||
|
218 | lua = """local keys = redis.call('keys', ARGV[1]) | |||
|
219 | for i=1,#keys,5000 do | |||
|
220 | redis.call('del', unpack(keys, i, math.min(i+(5000-1), #keys))) | |||
|
221 | end | |||
|
222 | return #keys""" | |||
|
223 | num_affected_keys = self.writer_client.eval( | |||
|
224 | lua, | |||
|
225 | 0, | |||
|
226 | f"{prefix}*") | |||
|
227 | else: | |||
|
228 | cache_keys = self.list_keys(prefix=prefix) | |||
|
229 | num_affected_keys = len(cache_keys) | |||
|
230 | if num_affected_keys: | |||
|
231 | self.delete_multi(cache_keys) | |||
|
232 | return num_affected_keys | |||
|
233 | ||||
198 | def get_store(self): |
|
234 | def get_store(self): | |
199 | return self.reader_client.connection_pool |
|
235 | return self.reader_client.connection_pool | |
200 |
|
236 |
@@ -37,7 +37,7 b' log = logging.getLogger(__name__)' | |||||
37 | class RhodeCodeCacheRegion(CacheRegion): |
|
37 | class RhodeCodeCacheRegion(CacheRegion): | |
38 |
|
38 | |||
39 | def __repr__(self): |
|
39 | def __repr__(self): | |
40 | return f'{self.__class__}(name={self.name})' |
|
40 | return f'`{self.__class__.__name__}(name={self.name}, backend={self.backend.__class__})`' | |
41 |
|
41 | |||
42 | def conditional_cache_on_arguments( |
|
42 | def conditional_cache_on_arguments( | |
43 | self, namespace=None, |
|
43 | self, namespace=None, | |
@@ -224,14 +224,15 b' def get_or_create_region(region_name, re' | |||||
224 | return region_obj |
|
224 | return region_obj | |
225 |
|
225 | |||
226 |
|
226 | |||
227 | def clear_cache_namespace(cache_region: str | RhodeCodeCacheRegion, cache_namespace_uid: str, method: str): |
|
227 | def clear_cache_namespace(cache_region: str | RhodeCodeCacheRegion, cache_namespace_uid: str, method: str) -> int: | |
228 | from . import CLEAR_DELETE, CLEAR_INVALIDATE |
|
228 | from . import CLEAR_DELETE, CLEAR_INVALIDATE | |
229 |
|
229 | |||
230 | if not isinstance(cache_region, RhodeCodeCacheRegion): |
|
230 | if not isinstance(cache_region, RhodeCodeCacheRegion): | |
231 | cache_region = get_or_create_region(cache_region, cache_namespace_uid) |
|
231 | cache_region = get_or_create_region(cache_region, cache_namespace_uid) | |
232 |
log.debug('clearing cache region: %s with method=%s', |
|
232 | log.debug('clearing cache region: %s [prefix:%s] with method=%s', | |
|
233 | cache_region, cache_namespace_uid, method) | |||
233 |
|
234 | |||
234 |
num_affected_keys = |
|
235 | num_affected_keys = 0 | |
235 |
|
236 | |||
236 | if method == CLEAR_INVALIDATE: |
|
237 | if method == CLEAR_INVALIDATE: | |
237 | # NOTE: The CacheRegion.invalidate() method’s default mode of |
|
238 | # NOTE: The CacheRegion.invalidate() method’s default mode of | |
@@ -240,9 +241,5 b' def clear_cache_namespace(cache_region: ' | |||||
240 | cache_region.invalidate(hard=True) |
|
241 | cache_region.invalidate(hard=True) | |
241 |
|
242 | |||
242 | if method == CLEAR_DELETE: |
|
243 | if method == CLEAR_DELETE: | |
243 |
|
|
244 | num_affected_keys = cache_region.backend.delete_multi_by_prefix(prefix=cache_namespace_uid) | |
244 | num_affected_keys = len(cache_keys) |
|
|||
245 | if num_affected_keys: |
|
|||
246 | cache_region.delete_multi(cache_keys) |
|
|||
247 |
|
||||
248 | return num_affected_keys |
|
245 | return num_affected_keys |
General Comments 0
You need to be logged in to leave comments.
Login now