mute user: Cache list of muter IDs.

This commit defines a new function `get_muting_users`
which will return a list of IDs of users who have muted
a given user.
Whenever someone mutes/unmutes  a user, the cache will be
flushed, and subsequently when that user sends a message,
the cache will be populated with the list of people who
have muted them (maybe empty).

This data is a good candidate for caching because-

1. The function will later be called from the message send
codepath, and we try to minimize database queries there.

2. The entries will be pretty tiny.

3. The entries won't churn too much. An average user will
send messages much more frequently than get muted/unmuted,
and the first time penalty of hitting the db and populating
the cache should ideally get amortized by avoiding several
DB lookups on subsequent message sends.

The actual code to call this function will be written in
further commits.
This commit is contained in:
Abhijeet Prasad Bodas
2021-03-27 18:01:26 +05:30
committed by Tim Abbott
parent 9602aa1467
commit b140c17441
4 changed files with 56 additions and 2 deletions

View File

@@ -1,6 +1,7 @@
import datetime
from typing import Dict, List, Optional
from typing import Dict, List, Optional, Set
from zerver.lib.cache import cache_with_key, get_muting_users_cache_key
from zerver.lib.timestamp import datetime_to_timestamp
from zerver.models import MutedUser, UserProfile
@@ -34,3 +35,18 @@ def get_mute_object(user_profile: UserProfile, muted_user: UserProfile) -> Optio
return MutedUser.objects.get(user_profile=user_profile, muted_user=muted_user)
except MutedUser.DoesNotExist:
return None
@cache_with_key(get_muting_users_cache_key, timeout=3600 * 24 * 7)
def get_muting_users(muted_user: UserProfile) -> Set[int]:
"""
This is kind of the inverse of `get_user_mutes` above.
While `get_user_mutes` is mainly used for event system work,
this is used in the message send codepath, to get a list
of IDs of users who have muted a particular user.
The result will also include deactivated users.
"""
rows = MutedUser.objects.filter(
muted_user=muted_user,
).values("user_profile__id")
return {row["user_profile__id"] for row in rows}