From 7d50ef19d3a366c41cafb752e0d1ff12d69e182a Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Sat, 3 Jun 2023 21:25:04 +0530 Subject: [PATCH] perf: Delete multiple keys in O(1) redis calls Currently we call redis for each key, redis already supports deleting multiple keys in one go. --- frappe/tests/test_caching.py | 15 +++++++++++++++ frappe/utils/redis_wrapper.py | 20 +++++++++++--------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/frappe/tests/test_caching.py b/frappe/tests/test_caching.py index b9f7c66887..c71f116649 100644 --- a/frappe/tests/test_caching.py +++ b/frappe/tests/test_caching.py @@ -210,3 +210,18 @@ class TestDocumentCache(FrappeAPITestCase): with self.assertQueryCount(0): frappe.get_cached_doc(self.TEST_DOCTYPE, self.TEST_DOCNAME) + + +class TestRedisWrapper(FrappeAPITestCase): + def test_delete_keys(self): + + c = frappe.cache() + + prefix = "test_del_" + + for i in range(5): + c.set_value(f"{prefix}{i}", 1) + + self.assertEqual(len(c.get_keys(prefix)), 5) + c.delete_keys(prefix) + self.assertEqual(len(c.get_keys(prefix)), 0) diff --git a/frappe/utils/redis_wrapper.py b/frappe/utils/redis_wrapper.py index 3b335b2c1d..eb3ea3707e 100644 --- a/frappe/utils/redis_wrapper.py +++ b/frappe/utils/redis_wrapper.py @@ -127,20 +127,22 @@ class RedisWrapper(redis.Redis): def delete_value(self, keys, user=None, make_keys=True, shared=False): """Delete value, list of values.""" + if not keys: + return + if not isinstance(keys, (list, tuple)): keys = (keys,) + if make_keys: + keys = [self.make_key(k, shared=shared, user=user) for k in keys] + for key in keys: - if make_keys: - key = self.make_key(key, shared=shared) + frappe.local.cache.pop(key, None) - if key in frappe.local.cache: - del frappe.local.cache[key] - - try: - self.delete(key) - except redis.exceptions.ConnectionError: - pass + try: + self.delete(*keys) + except redis.exceptions.ConnectionError: + pass def lpush(self, key, value): super().lpush(self.make_key(key), value)