Cache realm user basic info dict that is used in bugdown

(imported from commit 688c47daceb73534be90bd98a031c7b4edb5546e)
This commit is contained in:
Leo Franchi
2013-10-23 17:16:39 -04:00
parent b26f158020
commit e1557bef73
5 changed files with 30 additions and 21 deletions

View File

@@ -12,7 +12,7 @@ from zerver.models import Realm, RealmEmoji, Stream, UserProfile, UserActivity,
to_dict_cache_key, get_realm, stringify_message_dict, bulk_get_recipients, \ to_dict_cache_key, get_realm, stringify_message_dict, bulk_get_recipients, \
email_to_domain, email_to_username, display_recipient_cache_key, \ email_to_domain, email_to_username, display_recipient_cache_key, \
get_stream_cache_key, to_dict_cache_key_id, is_super_user, \ get_stream_cache_key, to_dict_cache_key_id, is_super_user, \
get_active_user_profiles_by_realm, UserActivityInterval UserActivityInterval, get_active_user_dicts_in_realm
from django.db import transaction, IntegrityError from django.db import transaction, IntegrityError
from django.db.models import F, Q from django.db.models import F, Q
@@ -79,7 +79,7 @@ def log_event(event):
log.write(ujson.dumps(event) + '\n') log.write(ujson.dumps(event) + '\n')
def active_user_ids(realm): def active_user_ids(realm):
return [up.id for up in get_active_user_profiles_by_realm(realm)] return [userdict['id'] for userdict in get_active_user_dicts_in_realm(realm)]
def notify_created_user(user_profile): def notify_created_user(user_profile):
notice = dict(event=dict(type="realm_user", op="add", notice = dict(event=dict(type="realm_user", op="add",
@@ -365,7 +365,7 @@ def do_create_stream(realm, stream_name):
stream.name = stream_name stream.name = stream_name
stream.save() stream.save()
Recipient.objects.create(type_id=stream.id, type=Recipient.STREAM) Recipient.objects.create(type_id=stream.id, type=Recipient.STREAM)
subscribers = get_active_user_profiles_by_realm(realm).filter(is_bot=False) subscribers = UserProfile.objects.filter(realm=realm, is_active=True, is_bot=False)
bulk_add_subscriptions([stream], subscribers) bulk_add_subscriptions([stream], subscribers)
def create_stream_if_needed(realm, stream_name, invite_only=False): def create_stream_if_needed(realm, stream_name, invite_only=False):
@@ -1668,10 +1668,10 @@ def do_events_register(user_profile, user_client, apply_markdown=True,
if event_types is None or "pointer" in event_types: if event_types is None or "pointer" in event_types:
ret['pointer'] = user_profile.pointer ret['pointer'] = user_profile.pointer
if event_types is None or "realm_user" in event_types: if event_types is None or "realm_user" in event_types:
ret['realm_users'] = [{'email' : profile.email, ret['realm_users'] = [{'email' : userdict['email'],
'is_bot' : profile.is_bot, 'is_bot' : userdict['is_bot'],
'full_name' : profile.full_name} 'full_name' : userdict['full_name']}
for profile in get_active_user_profiles_by_realm(user_profile.realm)] for userdict in get_active_user_dicts_in_realm(user_profile.realm)]
if event_types is None or "onboarding_steps" in event_types: if event_types is None or "onboarding_steps" in event_types:
ret['onboarding_steps'] = {'email' : user_profile.email, ret['onboarding_steps'] = {'email' : user_profile.email,
'steps' : user_profile.onboarding_steps} 'steps' : user_profile.onboarding_steps}
@@ -2085,7 +2085,7 @@ Referred: %s""" % (user_profile.full_name, user_profile.email, user_profile.real
def notify_realm_emoji(realm): def notify_realm_emoji(realm):
notice = dict(event=dict(type="realm_emoji", op="update", notice = dict(event=dict(type="realm_emoji", op="update",
realm_emoji=realm.get_emoji()), realm_emoji=realm.get_emoji()),
users=[up.id for up in get_active_user_profiles_by_realm(realm)]) users=[userdict['id'] for userdict in get_active_user_dicts_in_realm(realm)])
tornado_callbacks.send_notification(notice) tornado_callbacks.send_notification(notice)
def do_add_realm_emoji(realm, name, img_url): def do_add_realm_emoji(realm, name, img_url):

View File

@@ -768,7 +768,7 @@ db_data = None
def do_convert(md, realm_domain=None, message=None): def do_convert(md, realm_domain=None, message=None):
"""Convert Markdown to HTML, with Zulip-specific settings and hacks.""" """Convert Markdown to HTML, with Zulip-specific settings and hacks."""
from zerver.models import UserProfile from zerver.models import get_active_user_dicts_in_realm
if realm_domain in md_engines: if realm_domain in md_engines:
_md_engine = md_engines[realm_domain] _md_engine = md_engines[realm_domain]
@@ -783,8 +783,7 @@ def do_convert(md, realm_domain=None, message=None):
# Pre-fetch data from the DB that is used in the bugdown thread # Pre-fetch data from the DB that is used in the bugdown thread
global db_data global db_data
if message: if message:
realm_users = UserProfile.objects.filter(realm=message.get_realm(), is_active=True) \ realm_users = get_active_user_dicts_in_realm(message.get_realm())
.values('id', 'full_name', 'short_name', 'email')
db_data = {'realm_alert_words': alert_words.alert_words_in_realm(message.get_realm()), db_data = {'realm_alert_words': alert_words.alert_words_in_realm(message.get_realm()),
'full_names': dict((user['full_name'].lower(), user) for user in realm_users), 'full_names': dict((user['full_name'].lower(), user) for user in realm_users),

View File

@@ -236,6 +236,9 @@ def user_profile_by_id_cache_key(user_profile_id):
def cache_save_user_profile(user_profile): def cache_save_user_profile(user_profile):
cache_set(user_profile_by_id_cache_key(user_profile.id), user_profile, timeout=3600*24*7) cache_set(user_profile_by_id_cache_key(user_profile.id), user_profile, timeout=3600*24*7)
def active_user_dicts_in_realm_cache_key(realm):
return "active_user_dicts_in_realm:%s" % (realm.id,)
# Called by models.py to flush the user_profile cache whenever we save # Called by models.py to flush the user_profile cache whenever we save
# a user_profile object # a user_profile object
def update_user_profile_cache(sender, **kwargs): def update_user_profile_cache(sender, **kwargs):
@@ -245,10 +248,16 @@ def update_user_profile_cache(sender, **kwargs):
items_for_memcached[user_profile_by_id_cache_key(user_profile.id)] = (user_profile,) items_for_memcached[user_profile_by_id_cache_key(user_profile.id)] = (user_profile,)
cache_set_many(items_for_memcached) cache_set_many(items_for_memcached)
# Invalidate our active_users_in_realm info dict if any user has changed
# name or email
if kwargs['update_fields'] is None or \
len(set(['full_name', 'short_name', 'email']) & set(kwargs['update_fields'])) > 0:
cache_delete(active_user_dicts_in_realm_cache_key(user_profile.realm))
# Invalidate realm-wide alert words cache if any user in the realm has changed # Invalidate realm-wide alert words cache if any user in the realm has changed
# alert words # alert words
if kwargs['update_fields'] is None or "alert_words" in kwargs['update_fields']: if kwargs['update_fields'] is None or "alert_words" in kwargs['update_fields']:
djcache.delete(KEY_PREFIX + realm_alert_words_cache_key(user_profile.realm)) cache_delete(realm_alert_words_cache_key(user_profile.realm))
def realm_alert_words_cache_key(realm): def realm_alert_words_cache_key(realm):
return "realm_alert_words:%s" % (realm.domain,) return "realm_alert_words:%s" % (realm.domain,)

View File

@@ -7,7 +7,7 @@ from django.contrib.auth.models import AbstractBaseUser, UserManager, \
from zerver.lib.cache import cache_with_key, update_user_profile_cache, \ from zerver.lib.cache import cache_with_key, update_user_profile_cache, \
user_profile_by_id_cache_key, user_profile_by_email_cache_key, \ user_profile_by_id_cache_key, user_profile_by_email_cache_key, \
generic_bulk_cached_fetch, cache_set, \ generic_bulk_cached_fetch, cache_set, \
display_recipient_cache_key display_recipient_cache_key, active_user_dicts_in_realm_cache_key
from zerver.lib.utils import make_safe_digest, generate_random_token from zerver.lib.utils import make_safe_digest, generate_random_token
from django.db import transaction, IntegrityError from django.db import transaction, IntegrityError
from zerver.lib import bugdown from zerver.lib import bugdown
@@ -816,9 +816,10 @@ def get_user_profile_by_id(uid):
def get_user_profile_by_email(email): def get_user_profile_by_email(email):
return UserProfile.objects.select_related().get(email__iexact=email) return UserProfile.objects.select_related().get(email__iexact=email)
def get_active_user_profiles_by_realm(realm): @cache_with_key(active_user_dicts_in_realm_cache_key, timeout=3600*24*7)
return UserProfile.objects.select_related().filter(realm=realm, def get_active_user_dicts_in_realm(realm):
is_active=True) return UserProfile.objects.filter(realm=realm, is_active=True) \
.values('id', 'full_name', 'short_name', 'email', 'is_bot')
def get_prereg_user_by_email(email): def get_prereg_user_by_email(email):
# A user can be invited many times, so only return the result of the latest # A user can be invited many times, so only return the result of the latest

View File

@@ -24,7 +24,7 @@ from zerver.models import Message, UserProfile, Stream, Subscription, \
get_recipient, valid_stream_name, to_dict_cache_key, to_dict_cache_key_id, \ get_recipient, valid_stream_name, to_dict_cache_key, to_dict_cache_key_id, \
extract_message_dict, stringify_message_dict, parse_usermessage_flags, \ extract_message_dict, stringify_message_dict, parse_usermessage_flags, \
email_to_domain, email_to_username, get_realm, completely_open, \ email_to_domain, email_to_username, get_realm, completely_open, \
is_super_user, get_active_user_profiles_by_realm, AppleDeviceToken is_super_user, AppleDeviceToken, get_active_user_dicts_in_realm
from zerver.lib.actions import do_remove_subscription, bulk_remove_subscriptions, \ from zerver.lib.actions import do_remove_subscription, bulk_remove_subscriptions, \
do_change_password, create_mirror_user_if_needed, compute_irc_user_fullname, \ do_change_password, create_mirror_user_if_needed, compute_irc_user_fullname, \
do_change_full_name, \ do_change_full_name, \
@@ -151,7 +151,7 @@ def send_signup_message(sender, signups_stream, user_profile,
# Send notification to realm notifications stream if it exists # Send notification to realm notifications stream if it exists
# Don't send notification for the first user in a realm # Don't send notification for the first user in a realm
realm_user_count = get_active_user_profiles_by_realm(user_profile.realm).count() realm_user_count = len(get_active_user_dicts_in_realm(user_profile.realm))
if user_profile.realm.notifications_stream is not None and realm_user_count > 1: if user_profile.realm.notifications_stream is not None and realm_user_count > 1:
internal_send_message(sender, "stream", internal_send_message(sender, "stream",
user_profile.realm.notifications_stream.name, user_profile.realm.notifications_stream.name,
@@ -1597,14 +1597,14 @@ def add_subscriptions_backend(request, user_profile,
msg = ("Hi there! %s just created a new stream '%s'. " msg = ("Hi there! %s just created a new stream '%s'. "
"To join, click the gear in the left-side streams list." "To join, click the gear in the left-side streams list."
% (user_profile.full_name, created_streams[0].name)) % (user_profile.full_name, created_streams[0].name))
for realm_user in get_active_user_profiles_by_realm(user_profile.realm): for realm_user_dict in get_active_user_dicts_in_realm(user_profile.realm):
# Don't announce to yourself or to people you explicitly added # Don't announce to yourself or to people you explicitly added
# (who will get the notification above instead). # (who will get the notification above instead).
if realm_user.email in principals or realm_user.email == user_profile.email: if realm_user_dict['email'] in principals or realm_user_dict['email'] == user_profile.email:
continue continue
notifications.append(internal_prep_message("notification-bot@zulip.com", notifications.append(internal_prep_message("notification-bot@zulip.com",
"private", "private",
realm_user.email, "", msg)) realm_user_dict['email'], "", msg))
if len(notifications) > 0: if len(notifications) > 0:
do_send_messages(notifications) do_send_messages(notifications)