From e2d010ef2d50b6b4ad43ddd6b48cfdcfda98d19c Mon Sep 17 00:00:00 2001 From: Tim Abbott Date: Tue, 26 Mar 2013 13:51:55 -0400 Subject: [PATCH] Fix most unnecessary database queries in huddle creation. This saves 2 database queries per user in the huddle when sending the first message to a particular huddle. (imported from commit f71aa32df846fb4b82651a93ff9608087ffcaa5a) --- zephyr/lib/actions.py | 7 ++----- zephyr/lib/cache.py | 1 - zephyr/management/commands/populate_db.py | 5 ++--- zephyr/models.py | 19 ++++++++++++------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/zephyr/lib/actions.py b/zephyr/lib/actions.py index f6c1cbb169..2d80bbcc73 100644 --- a/zephyr/lib/actions.py +++ b/zephyr/lib/actions.py @@ -4,7 +4,8 @@ from zephyr.lib.context_managers import lockfile from zephyr.models import Realm, Stream, UserProfile, UserActivity, \ Subscription, Recipient, Message, UserMessage, valid_stream_name, \ DefaultStream, StreamColor, UserPresence, MAX_SUBJECT_LENGTH, \ - MAX_MESSAGE_LENGTH, get_client, get_stream, get_recipient, get_huddle + MAX_MESSAGE_LENGTH, get_client, get_stream, get_recipient, get_huddle, \ + get_user_profile_by_id from django.db import transaction, IntegrityError from django.db.models import F from django.core.exceptions import ValidationError @@ -130,10 +131,6 @@ def log_message(message): if not message.sending_client.name.startswith("test:"): log_event(message.to_log_dict()) -@cache_with_key(user_profile_by_id_cache_key) -def get_user_profile_by_id(uid): - return UserProfile.objects.select_related().get(id=uid) - def do_send_message(message, rendered_content=None, no_log=False, stream=None): # Log the message to our message log for populate_db to refill diff --git a/zephyr/lib/cache.py b/zephyr/lib/cache.py index 4a02ba3822..5b078a814b 100644 --- a/zephyr/lib/cache.py +++ b/zephyr/lib/cache.py @@ -88,4 +88,3 @@ def update_user_cache(sender, **kwargs): items_for_memcached = {} items_for_memcached[user_by_id_cache_key(user.id)] = (user,) djcache.set_many(items_for_memcached) - diff --git a/zephyr/management/commands/populate_db.py b/zephyr/management/commands/populate_db.py index 0c01611121..124f87f928 100644 --- a/zephyr/management/commands/populate_db.py +++ b/zephyr/management/commands/populate_db.py @@ -5,9 +5,8 @@ from django.contrib.auth.models import User from django.contrib.sites.models import Site from zephyr.models import Message, UserProfile, Stream, Recipient, Client, \ Subscription, Huddle, get_huddle, Realm, UserMessage, StreamColor, \ - get_huddle_hash, clear_database, get_client -from zephyr.lib.actions import get_user_profile_by_id, \ - do_send_message, set_default_streams, do_activate_user + get_huddle_hash, clear_database, get_client, get_user_profile_by_id +from zephyr.lib.actions import do_send_message, set_default_streams, do_activate_user from zephyr.lib.parallel import run_parallel from django.db import transaction, connection from django.conf import settings diff --git a/zephyr/models.py b/zephyr/models.py index 4df3982782..401d80f8ce 100644 --- a/zephyr/models.py +++ b/zephyr/models.py @@ -2,7 +2,7 @@ from django.db import models from django.conf import settings from django.contrib.auth.models import User from zephyr.lib.cache import cache_with_key, update_user_profile_cache, \ - update_user_cache + update_user_cache, user_profile_by_id_cache_key from zephyr.lib.initial_password import initial_api_key from zephyr.lib.utils import make_safe_digest import os @@ -332,6 +332,10 @@ class Subscription(models.Model): def __str__(self): return self.__repr__() +@cache_with_key(user_profile_by_id_cache_key) +def get_user_profile_by_id(uid): + return UserProfile.objects.select_related().get(id=uid) + class Huddle(models.Model): # TODO: We should consider whether using # CommaSeparatedIntegerField would be better. @@ -353,12 +357,13 @@ def get_huddle(id_list): def get_huddle_backend(huddle_hash, id_list): (huddle, created) = Huddle.objects.get_or_create(huddle_hash=huddle_hash) if created: - recipient = Recipient.objects.create(type_id=huddle.id, - type=Recipient.HUDDLE) - # Add subscriptions - for uid in id_list: - Subscription.objects.create(recipient = recipient, - user_profile = UserProfile.objects.get(id=uid)) + with transaction.commit_on_success(): + recipient = Recipient.objects.create(type_id=huddle.id, + type=Recipient.HUDDLE) + subs_to_create = [Subscription(recipient=recipient, + user_profile=get_user_profile_by_id(user_profile_id)) + for user_profile_id in id_list] + Subscription.objects.bulk_create(subs_to_create) return huddle # This function is used only by tests.