From 279c2ba796370b06e319902796d40237a4725e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emanuel=20Sch=C3=BCtze?= Date: Wed, 8 Nov 2017 10:34:47 +0100 Subject: [PATCH] Adds elements to restricted data cache only if cache already exists (hotfix for #3427). Prevents corrupt cache if restricted data cache is cleared while runtime. --- openslides/utils/autoupdate.py | 4 ++-- openslides/utils/cache.py | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/openslides/utils/autoupdate.py b/openslides/utils/autoupdate.py index 4def9179a..c804f4f7d 100644 --- a/openslides/utils/autoupdate.py +++ b/openslides/utils/autoupdate.py @@ -99,7 +99,7 @@ def ws_add_site(message: Any) -> None: output.append(formatted_data) # Cache restricted data for user - restricted_data_cache.add_element( + restricted_data_cache.update_element( user_id, collection.collection_string, data['id'], @@ -293,7 +293,7 @@ def send_data(message: ChannelMessageFormat) -> None: for collection_element in collection_elements: formatted_data = collection_element.as_autoupdate_for_user(user) if formatted_data['action'] == 'changed': - restricted_data_cache.add_element( + restricted_data_cache.update_element( user_id or 0, collection_element.collection_string, collection_element.id, diff --git a/openslides/utils/cache.py b/openslides/utils/cache.py index b9f6ae6eb..1cb16d31f 100644 --- a/openslides/utils/cache.py +++ b/openslides/utils/cache.py @@ -363,6 +363,17 @@ class RestrictedDataCache: base_cache_key = 'restricted_user_cache' + def update_element(self, user_id: int, collection_string: str, id: int, data: object) -> None: + """ + Adds on element to the cache only if the cache exists for the user. + + Note: This method is not atomic. So in very rare cases it is possible + that the restricted date cache can become corrupt. The best solution would be to + use a lua script instead. See also #3427. + """ + if self.exists_for_user(user_id): + self.add_element(user_id, collection_string, id, data) + def add_element(self, user_id: int, collection_string: str, id: int, data: object) -> None: """ Adds one element to the cache. If the cache does not exists for the user, @@ -413,6 +424,9 @@ class DummyRestrictedDataCache: Dummy RestrictedDataCache that does nothing. """ + def update_element(self, user_id: int, collection_string: str, id: int, data: object) -> None: + pass + def add_element(self, user_id: int, collection_string: str, id: int, data: object) -> None: pass