From 524df5cbc808ad6e4839133b59fc8e9a8918f9c1 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 15 Jan 2024 17:49:28 +0100 Subject: [PATCH] Cache: delete_pattern --- app/scodoc/sco_cache.py | 27 +++++++++++++++++++++++++++ sco_version.py | 2 +- tests/unit/test_caches.py | 4 ++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/app/scodoc/sco_cache.py b/app/scodoc/sco_cache.py index 4c9960dfd..e31b6a18d 100644 --- a/app/scodoc/sco_cache.py +++ b/app/scodoc/sco_cache.py @@ -121,6 +121,33 @@ class ScoDocCache: for oid in oids: cls.delete(oid) + @classmethod + def delete_pattern(cls, pattern: str, std_prefix=True) -> int: + """Delete all keys matching pattern. + The pattern starts with flask_cache_. + If std_prefix is true (default), the prefix is added + to the given pattern. + Examples: + 'TABASSI_tableau-etud-1234:*' + Or, with std_prefix false, 'flask_cache_RT_TABASSI_tableau-etud-1234:*' + + Returns number of keys deleted. + """ + # see https://stackoverflow.com/questions/36708461/flask-cache-list-keys-based-on-a-pattern + assert CACHE.cache.__class__.__name__ == "RedisCache" # Redis specific + import redis + + if std_prefix: + pattern = "flask_cache_" + g.scodoc_dept + "_" + cls.prefix + "_" + pattern + + r = redis.Redis() + count = 0 + for key in r.scan_iter(pattern): + log(f"{cls.__name__}.delete_pattern({key})") + r.delete(key) + count += 1 + return count + class EvaluationCache(ScoDocCache): """Cache for evaluations. diff --git a/sco_version.py b/sco_version.py index 53da13f95..7b986ac6c 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.6.77" +SCOVERSION = "9.6.78" SCONAME = "ScoDoc" diff --git a/tests/unit/test_caches.py b/tests/unit/test_caches.py index 3a4882d77..0e3766ba0 100644 --- a/tests/unit/test_caches.py +++ b/tests/unit/test_caches.py @@ -48,6 +48,10 @@ def test_notes_table(test_client): # XXX A REVOIR POUR TESTER RES TODO formsemestre_id = sem["formsemestre_id"] nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) assert sco_cache.ResultatsSemestreCache.get(formsemestre_id) + # Efface les semestres + sco_cache.ResultatsSemestreCache.delete_pattern("*") + for sem in sems[:10]: + assert sco_cache.ResultatsSemestreCache.get(formsemestre_id) is None def test_cache_evaluations(test_client):