Show More
@@ -145,7 +145,7 b' dev-srv:' | |||||
145 | .PHONY: dev-srv-g |
|
145 | .PHONY: dev-srv-g | |
146 | ## run gunicorn multi process workers |
|
146 | ## run gunicorn multi process workers | |
147 | dev-srv-g: |
|
147 | dev-srv-g: | |
148 |
gunicorn |
|
148 | gunicorn --paste .dev/dev.ini --bind=0.0.0.0:10020 --config=.dev/gunicorn_config.py --timeout=120 | |
149 |
|
149 | |||
150 |
|
150 | |||
151 | # Default command on calling make |
|
151 | # Default command on calling make |
@@ -44,7 +44,7 b' def trigger_user_permission_flush(event)' | |||||
44 | for user_id in affected_user_ids: |
|
44 | for user_id in affected_user_ids: | |
45 | for cache_namespace_uid_tmpl in cache_namespaces: |
|
45 | for cache_namespace_uid_tmpl in cache_namespaces: | |
46 | cache_namespace_uid = cache_namespace_uid_tmpl.format(user_id) |
|
46 | cache_namespace_uid = cache_namespace_uid_tmpl.format(user_id) | |
47 |
del_keys = rc_cache.clear_cache_namespace('cache_perms', cache_namespace_uid, method=rc_cache.CLEAR_ |
|
47 | del_keys = rc_cache.clear_cache_namespace('cache_perms', cache_namespace_uid, method=rc_cache.CLEAR_DELETE) | |
48 | log.debug('Invalidated %s cache keys for user_id: %s and namespace %s', |
|
48 | log.debug('Invalidated %s cache keys for user_id: %s and namespace %s', | |
49 | del_keys, user_id, cache_namespace_uid) |
|
49 | del_keys, user_id, cache_namespace_uid) | |
50 |
|
50 |
@@ -1313,7 +1313,7 b' class UsersView(UserAppView):' | |||||
1313 | c.perm_user = c.user.AuthUser(ip_addr=self.request.remote_addr) |
|
1313 | c.perm_user = c.user.AuthUser(ip_addr=self.request.remote_addr) | |
1314 |
|
1314 | |||
1315 | cache_namespace_uid = f'cache_user_auth.{rc_cache.PERMISSIONS_CACHE_VER}.{self.db_user.user_id}' |
|
1315 | cache_namespace_uid = f'cache_user_auth.{rc_cache.PERMISSIONS_CACHE_VER}.{self.db_user.user_id}' | |
1316 | del_keys = rc_cache.clear_cache_namespace('cache_perms', cache_namespace_uid) |
|
1316 | del_keys = rc_cache.clear_cache_namespace('cache_perms', cache_namespace_uid, method=rc_cache.CLEAR_DELETE) | |
1317 |
|
1317 | |||
1318 | h.flash(_("Deleted {} cache keys").format(del_keys), category='success') |
|
1318 | h.flash(_("Deleted {} cache keys").format(del_keys), category='success') | |
1319 |
|
1319 |
@@ -74,10 +74,20 b' class LRUMemoryBackend(memory_backend.Me' | |||||
74 | # we don't care if key isn't there at deletion |
|
74 | # we don't care if key isn't there at deletion | |
75 | pass |
|
75 | pass | |
76 |
|
76 | |||
|
77 | def list_keys(self, prefix): | |||
|
78 | return list(self._cache.keys()) | |||
|
79 | ||||
77 | def delete_multi(self, keys): |
|
80 | def delete_multi(self, keys): | |
78 | for key in keys: |
|
81 | for key in keys: | |
79 | self.delete(key) |
|
82 | self.delete(key) | |
80 |
|
83 | |||
|
84 | def delete_multi_by_prefix(self, prefix): | |||
|
85 | cache_keys = self.list_keys(prefix=prefix) | |||
|
86 | num_affected_keys = len(cache_keys) | |||
|
87 | if num_affected_keys: | |||
|
88 | self.delete_multi(cache_keys) | |||
|
89 | return num_affected_keys | |||
|
90 | ||||
81 |
|
91 | |||
82 | class PickleSerializer: |
|
92 | class PickleSerializer: | |
83 | serializer: None | Serializer = staticmethod( # type: ignore |
|
93 | serializer: None | Serializer = staticmethod( # type: ignore | |
@@ -178,6 +188,13 b' class FileNamespaceBackend(PickleSeriali' | |||||
178 | log.error('Failed to fetch DBM keys from DB: %s', self.get_store()) |
|
188 | log.error('Failed to fetch DBM keys from DB: %s', self.get_store()) | |
179 | raise |
|
189 | raise | |
180 |
|
190 | |||
|
191 | def delete_multi_by_prefix(self, prefix): | |||
|
192 | cache_keys = self.list_keys(prefix=prefix) | |||
|
193 | num_affected_keys = len(cache_keys) | |||
|
194 | if num_affected_keys: | |||
|
195 | self.delete_multi(cache_keys) | |||
|
196 | return num_affected_keys | |||
|
197 | ||||
181 | def get_store(self): |
|
198 | def get_store(self): | |
182 | return self.filename |
|
199 | return self.filename | |
183 |
|
200 | |||
@@ -227,6 +244,25 b' class BaseRedisBackend(redis_backend.Red' | |||||
227 | prefix = self._get_keys_pattern(prefix) |
|
244 | prefix = self._get_keys_pattern(prefix) | |
228 | return self.reader_client.keys(prefix) |
|
245 | return self.reader_client.keys(prefix) | |
229 |
|
246 | |||
|
247 | def delete_multi_by_prefix(self, prefix, use_lua=False): | |||
|
248 | if use_lua: | |||
|
249 | # high efficient LUA script to delete ALL keys by prefix... | |||
|
250 | lua = """local keys = redis.call('keys', ARGV[1]) | |||
|
251 | for i=1,#keys,5000 do | |||
|
252 | redis.call('del', unpack(keys, i, math.min(i+(5000-1), #keys))) | |||
|
253 | end | |||
|
254 | return #keys""" | |||
|
255 | num_affected_keys = self.writer_client.eval( | |||
|
256 | lua, | |||
|
257 | 0, | |||
|
258 | f"{prefix}*") | |||
|
259 | else: | |||
|
260 | cache_keys = self.list_keys(prefix=prefix) | |||
|
261 | num_affected_keys = len(cache_keys) | |||
|
262 | if num_affected_keys: | |||
|
263 | self.delete_multi(cache_keys) | |||
|
264 | return num_affected_keys | |||
|
265 | ||||
230 | def get_store(self): |
|
266 | def get_store(self): | |
231 | return self.reader_client.connection_pool |
|
267 | return self.reader_client.connection_pool | |
232 |
|
268 |
@@ -232,14 +232,15 b' def get_or_create_region(region_name, re' | |||||
232 | return region_obj |
|
232 | return region_obj | |
233 |
|
233 | |||
234 |
|
234 | |||
235 | def clear_cache_namespace(cache_region: str | RhodeCodeCacheRegion, cache_namespace_uid: str, method: str): |
|
235 | def clear_cache_namespace(cache_region: str | RhodeCodeCacheRegion, cache_namespace_uid: str, method: str) -> int: | |
236 | from . import CLEAR_DELETE, CLEAR_INVALIDATE |
|
236 | from . import CLEAR_DELETE, CLEAR_INVALIDATE | |
237 |
|
237 | |||
238 | if not isinstance(cache_region, RhodeCodeCacheRegion): |
|
238 | if not isinstance(cache_region, RhodeCodeCacheRegion): | |
239 | cache_region = get_or_create_region(cache_region, cache_namespace_uid) |
|
239 | cache_region = get_or_create_region(cache_region, cache_namespace_uid) | |
240 |
log.debug('clearing cache region: %s with method=%s', |
|
240 | log.debug('clearing cache region: %s [prefix:%s] with method=%s', | |
|
241 | cache_region, cache_namespace_uid, method) | |||
241 |
|
242 | |||
242 |
num_affected_keys = |
|
243 | num_affected_keys = 0 | |
243 |
|
244 | |||
244 | if method == CLEAR_INVALIDATE: |
|
245 | if method == CLEAR_INVALIDATE: | |
245 | # NOTE: The CacheRegion.invalidate() method’s default mode of |
|
246 | # NOTE: The CacheRegion.invalidate() method’s default mode of | |
@@ -248,10 +249,7 b' def clear_cache_namespace(cache_region: ' | |||||
248 | cache_region.invalidate(hard=True) |
|
249 | cache_region.invalidate(hard=True) | |
249 |
|
250 | |||
250 | if method == CLEAR_DELETE: |
|
251 | if method == CLEAR_DELETE: | |
251 |
|
|
252 | num_affected_keys = cache_region.backend.delete_multi_by_prefix(prefix=cache_namespace_uid) | |
252 | num_affected_keys = len(cache_keys) |
|
|||
253 | if num_affected_keys: |
|
|||
254 | cache_region.delete_multi(cache_keys) |
|
|||
255 |
|
253 | |||
256 | return num_affected_keys |
|
254 | return num_affected_keys | |
257 |
|
255 |
General Comments 0
You need to be logged in to leave comments.
Login now