alert_words: Refactor the code to flush alert_words cache.

Subsequent commits will add "on_delete=models.RESTRICT"
relationships, which will result in the AlertWord
objects being deleted after Realm has been deleted from
the database.

In order to handle this, we update realm_alert_words_cache_key,
realm_alert_words_automaton_cache_key, and flush_realm_alert_words
functions to accept realm_id as parameter instead of realm
object, so that  the code for flushing the cache works even
after the realm is deleted. This change is fine because
eventually only realm_id is used by these functions and there
is no need of the complete realm object.
This commit is contained in:
Ujjawal Modi 2023-06-09 01:47:05 +05:30 committed by Tim Abbott
parent f7346f36fc
commit a361c23aac
3 changed files with 14 additions and 14 deletions

View File

@ -11,7 +11,7 @@ from zerver.lib.cache import (
from zerver.models import AlertWord, Realm, UserProfile, flush_realm_alert_words from zerver.models import AlertWord, Realm, UserProfile, flush_realm_alert_words
@cache_with_key(realm_alert_words_cache_key, timeout=3600 * 24) @cache_with_key(lambda realm: realm_alert_words_cache_key(realm.id), timeout=3600 * 24)
def alert_words_in_realm(realm: Realm) -> Dict[int, List[str]]: def alert_words_in_realm(realm: Realm) -> Dict[int, List[str]]:
user_ids_and_words = AlertWord.objects.filter(realm=realm, user_profile__is_active=True).values( user_ids_and_words = AlertWord.objects.filter(realm=realm, user_profile__is_active=True).values(
"user_profile_id", "word" "user_profile_id", "word"
@ -23,7 +23,7 @@ def alert_words_in_realm(realm: Realm) -> Dict[int, List[str]]:
return user_ids_with_words return user_ids_with_words
@cache_with_key(realm_alert_words_automaton_cache_key, timeout=3600 * 24) @cache_with_key(lambda realm: realm_alert_words_automaton_cache_key(realm.id), timeout=3600 * 24)
def get_alert_word_automaton(realm: Realm) -> ahocorasick.Automaton: def get_alert_word_automaton(realm: Realm) -> ahocorasick.Automaton:
user_id_with_words = alert_words_in_realm(realm) user_id_with_words = alert_words_in_realm(realm)
alert_word_automaton = ahocorasick.Automaton() alert_word_automaton = ahocorasick.Automaton()
@ -66,7 +66,7 @@ def add_user_alert_words(user_profile: UserProfile, new_words: Iterable[str]) ->
for word in word_dict.values() for word in word_dict.values()
) )
# Django bulk_create operations don't flush caches, so we need to do this ourselves. # Django bulk_create operations don't flush caches, so we need to do this ourselves.
flush_realm_alert_words(user_profile.realm) flush_realm_alert_words(user_profile.realm_id)
return user_alert_words(user_profile) return user_alert_words(user_profile)

View File

@ -635,8 +635,8 @@ def flush_realm(
cache_delete(realm_user_dicts_cache_key(realm.id)) cache_delete(realm_user_dicts_cache_key(realm.id))
cache_delete(active_user_ids_cache_key(realm.id)) cache_delete(active_user_ids_cache_key(realm.id))
cache_delete(bot_dicts_in_realm_cache_key(realm.id)) cache_delete(bot_dicts_in_realm_cache_key(realm.id))
cache_delete(realm_alert_words_cache_key(realm)) cache_delete(realm_alert_words_cache_key(realm.id))
cache_delete(realm_alert_words_automaton_cache_key(realm)) cache_delete(realm_alert_words_automaton_cache_key(realm.id))
cache_delete(active_non_guest_user_ids_cache_key(realm.id)) cache_delete(active_non_guest_user_ids_cache_key(realm.id))
cache_delete(realm_rendered_description_cache_key(realm)) cache_delete(realm_rendered_description_cache_key(realm))
cache_delete(realm_text_description_cache_key(realm)) cache_delete(realm_text_description_cache_key(realm))
@ -645,12 +645,12 @@ def flush_realm(
cache_delete(realm_text_description_cache_key(realm)) cache_delete(realm_text_description_cache_key(realm))
def realm_alert_words_cache_key(realm: "Realm") -> str: def realm_alert_words_cache_key(realm_id: int) -> str:
return f"realm_alert_words:{realm.string_id}" return f"realm_alert_words:{realm_id}"
def realm_alert_words_automaton_cache_key(realm: "Realm") -> str: def realm_alert_words_automaton_cache_key(realm_id: int) -> str:
return f"realm_alert_words_automaton:{realm.string_id}" return f"realm_alert_words_automaton:{realm_id}"
def realm_rendered_description_cache_key(realm: "Realm") -> str: def realm_rendered_description_cache_key(realm: "Realm") -> str:

View File

@ -4949,14 +4949,14 @@ class AlertWord(models.Model):
unique_together = ("user_profile", "word") unique_together = ("user_profile", "word")
def flush_realm_alert_words(realm: Realm) -> None: def flush_realm_alert_words(realm_id: int) -> None:
cache_delete(realm_alert_words_cache_key(realm)) cache_delete(realm_alert_words_cache_key(realm_id))
cache_delete(realm_alert_words_automaton_cache_key(realm)) cache_delete(realm_alert_words_automaton_cache_key(realm_id))
def flush_alert_word(*, instance: AlertWord, **kwargs: object) -> None: def flush_alert_word(*, instance: AlertWord, **kwargs: object) -> None:
realm = instance.realm realm_id = instance.realm_id
flush_realm_alert_words(realm) flush_realm_alert_words(realm_id)
post_save.connect(flush_alert_word, sender=AlertWord) post_save.connect(flush_alert_word, sender=AlertWord)