From a23f6be28dc1bb2549d005ab15d4ea87835aa835 Mon Sep 17 00:00:00 2001 From: Tim Abbott Date: Mon, 18 Mar 2013 11:54:58 -0400 Subject: [PATCH] Cache the results of Recipient queries in our memcached cache. (imported from commit a6ba25a9c62d2738e4738b076370e4b2bc0ffaba) --- zephyr/lib/actions.py | 12 +++++------- zephyr/models.py | 4 ++++ zephyr/views.py | 24 +++++++++++------------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/zephyr/lib/actions.py b/zephyr/lib/actions.py index 1d45a1402e..9eaa7cec4a 100644 --- a/zephyr/lib/actions.py +++ b/zephyr/lib/actions.py @@ -4,7 +4,7 @@ from zephyr.lib.context_managers import lockfile from zephyr.models import Realm, Stream, UserProfile, UserActivity, \ Subscription, Recipient, Message, UserMessage, \ DefaultStream, StreamColor, UserPresence, \ - MAX_MESSAGE_LENGTH, get_client, get_stream + MAX_MESSAGE_LENGTH, get_client, get_stream, get_recipient from django.db import transaction, IntegrityError from django.db.models import F from zephyr.lib.initial_password import initial_password @@ -216,7 +216,7 @@ def internal_send_message(sender_email, recipient_type, recipient, else: type_id = UserProfile.objects.get(user__email__iexact=recipient).id - message.recipient = Recipient.objects.get(type_id=type_id, type=recipient_type) + message.recipient = get_recipient(recipient_type, type_id) message.subject = subject message.content = content @@ -248,7 +248,7 @@ def pick_color(user_profile): def get_subscription(stream_name, user_profile): stream = get_stream(stream_name, user_profile.realm) - recipient = Recipient.objects.get(type_id=stream.id, type=Recipient.STREAM) + recipient = get_recipient(Recipient.STREAM, stream.id) return Subscription.objects.filter(user_profile=user_profile, recipient=recipient, active=True) @@ -262,8 +262,7 @@ def set_stream_color(user_profile, stream_name, color=None): stream_color.save() def do_add_subscription(user_profile, stream, no_log=False): - recipient = Recipient.objects.get(type_id=stream.id, - type=Recipient.STREAM) + recipient = get_recipient(Recipient.STREAM, stream.id) (subscription, created) = Subscription.objects.get_or_create( user_profile=user_profile, recipient=recipient, defaults={'active': True}) @@ -281,8 +280,7 @@ def do_add_subscription(user_profile, stream, no_log=False): return did_subscribe def do_remove_subscription(user_profile, stream, no_log=False): - recipient = Recipient.objects.get(type_id=stream.id, - type=Recipient.STREAM) + recipient = get_recipient(Recipient.STREAM, stream.id) maybe_sub = Subscription.objects.filter(user_profile=user_profile, recipient=recipient) if len(maybe_sub) == 0: diff --git a/zephyr/models.py b/zephyr/models.py index deaf001d4f..93aa770c9a 100644 --- a/zephyr/models.py +++ b/zephyr/models.py @@ -192,6 +192,10 @@ def get_stream(stream_name, realm): except Stream.DoesNotExist: return None +@cache_with_key(lambda type, type_id: "get_recipient:%s:%s" % (type, type_id,)) +def get_recipient(type, type_id): + return Recipient.objects.get(type_id=type_id, type=type) + # NB: This function is currently unused, but may come in handy. def linebreak(string): return string.replace('\n\n', '

').replace('\n', '
') diff --git a/zephyr/views.py b/zephyr/views.py index ddeeae7d0d..2716bf6c31 100644 --- a/zephyr/views.py +++ b/zephyr/views.py @@ -15,7 +15,8 @@ from django.core.mail import send_mail, mail_admins from zephyr.models import Message, UserProfile, Stream, Subscription, \ Recipient, get_huddle, Realm, UserMessage, \ PreregistrationUser, get_client, MitUser, User, UserActivity, \ - MAX_SUBJECT_LENGTH, MAX_MESSAGE_LENGTH, get_stream, UserPresence + MAX_SUBJECT_LENGTH, MAX_MESSAGE_LENGTH, get_stream, UserPresence, \ + get_recipient from zephyr.lib.actions import do_add_subscription, do_remove_subscription, \ do_change_password, create_mit_user_if_needed, do_change_full_name, \ do_change_enable_desktop_notifications, do_change_enter_sends, \ @@ -520,7 +521,7 @@ class NarrowBuilder(object): stream = get_stream(operand, self.user_profile.realm) if stream is None: raise BadNarrowOperator('unknown stream ' + operand) - recipient = Recipient.objects.get(type=Recipient.STREAM, type_id=stream.id) + recipient = get_recipient(Recipient.STREAM, type_id=stream.id) return Q(message__recipient=recipient) def by_subject(self, operand): @@ -541,8 +542,7 @@ class NarrowBuilder(object): return Q(message__recipient=recipient) else: # Personal message - self_recipient = Recipient.objects.get(type=Recipient.PERSONAL, - type_id=self.user_profile.id) + self_recipient = get_recipient(Recipient.PERSONAL, type_id=self.user_profile.id) if operand == self.user_profile.user.email: # Personals with self return Q(message__recipient__type=Recipient.PERSONAL, @@ -554,8 +554,7 @@ class NarrowBuilder(object): except UserProfile.DoesNotExist: raise BadNarrowOperator('unknown user ' + operand) - narrow_recipient = Recipient.objects.get(type=Recipient.PERSONAL, - type_id=narrow_profile.id) + narrow_recipient = get_recipient(Recipient.PERSONAL, narrow_profile.id) return ((Q(message__sender=narrow_profile) & Q(message__recipient=self_recipient)) | (Q(message__sender=self.user_profile) & Q(message__recipient=narrow_recipient))) @@ -604,7 +603,7 @@ def get_old_messages_backend(request, anchor = POST(converter=int), user_profile=None, apply_markdown=True): if stream is not None: stream = get_public_stream(request, stream, user_profile.realm) - recipient = Recipient.objects.get(type_id=stream.id, type=Recipient.STREAM) + recipient = get_recipient(Recipient.STREAM, stream.id) query = UserMessage.objects.select_related('message').filter(message__recipient=recipient, user_profile=user_profile) \ .order_by('id') @@ -779,10 +778,9 @@ def recipient_for_emails(emails, not_forged_zephyr_mirror, user_profile, sender) # Make sure the sender is included in huddle messages recipient_profile_ids.add(sender.id) huddle = get_huddle(list(recipient_profile_ids)) - return Recipient.objects.get(type_id=huddle.id, type=Recipient.HUDDLE) + return get_recipient(Recipient.HUDDLE, huddle.id) else: - return Recipient.objects.get(type_id=list(recipient_profile_ids)[0], - type=Recipient.PERSONAL) + return get_recipient(Recipient.PERSONAL, list(recipient_profile_ids)[0]) @authenticated_json_post_view @has_request_variables @@ -890,7 +888,7 @@ def send_message_backend(request, user_profile, client, stream = get_stream(stream_name, user_profile.realm) if stream is None: return json_error("Stream does not exist") - recipient = Recipient.objects.get(type_id=stream.id, type=Recipient.STREAM) + recipient = get_recipient(Recipient.STREAM, stream.id) elif message_type_name == 'private': not_forged_zephyr_mirror = client and client.name == "zephyr_mirror" and not forged try: @@ -1127,7 +1125,7 @@ def json_stream_exists(request, user_profile, stream=POST): stream = get_stream(stream, user_profile.realm) result = {"exists": bool(stream)} if stream is not None: - recipient = Recipient.objects.get(type_id=stream.id, type=Recipient.STREAM) + recipient = get_recipient(Recipient.STREAM, stream.id) result["subscribed"] = Subscription.objects.filter(user_profile=user_profile, recipient=recipient, active=True).exists() @@ -1137,7 +1135,7 @@ def get_subscription_or_die(stream_name, user_profile): stream = get_stream(stream_name, user_profile.realm) if not stream: raise JsonableError("Invalid stream %s" % (stream.name,)) - recipient = Recipient.objects.get(type_id=stream.id, type=Recipient.STREAM) + recipient = get_recipient(Recipient.STREAM, stream.id) subscription = Subscription.objects.filter(user_profile=user_profile, recipient=recipient, active=True)