From 71bf6bcd303162761aa42f15d3ca697c95278f6f Mon Sep 17 00:00:00 2001 From: Ali Nawaz Date: Wed, 9 Oct 2024 18:12:10 +0500 Subject: [PATCH] perf: cache calls for calculating utm_source --- course_discovery/apps/api/cache.py | 4 ++++ course_discovery/apps/api/serializers.py | 6 ++++-- course_discovery/apps/api/utils.py | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/course_discovery/apps/api/cache.py b/course_discovery/apps/api/cache.py index b4e80e3e8d..c8cc4e4aa2 100644 --- a/course_discovery/apps/api/cache.py +++ b/course_discovery/apps/api/cache.py @@ -5,6 +5,7 @@ from django.conf import settings from django.core.cache import cache from django.http.response import HttpResponse +from edx_django_utils.cache import get_cache_key from rest_framework.renderers import JSONRenderer from rest_framework_extensions.cache.decorators import CacheResponse from rest_framework_extensions.key_constructor.bits import KeyBitBase, QueryParamsKeyBit @@ -165,3 +166,6 @@ def list(self, request, *args, **kwargs): ) def retrieve(self, request, *args, **kwargs): return super().retrieve(request, *args, **kwargs) + +def get_utm_source_request_cache_key(partner, user): + return get_cache_key(partner=partner.id, user=user.id) \ No newline at end of file diff --git a/course_discovery/apps/api/serializers.py b/course_discovery/apps/api/serializers.py index 05d5b7b3b7..b02dfef92b 100644 --- a/course_discovery/apps/api/serializers.py +++ b/course_discovery/apps/api/serializers.py @@ -17,6 +17,7 @@ from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ from django_countries.serializer_fields import CountryField +from edx_django_utils.cache import RequestCache, get_cache_key from localflavor.us.us_states import CONTIGUOUS_STATES from opaque_keys.edx.locator import CourseLocator from rest_flex_fields.serializers import FlexFieldsSerializerMixin @@ -28,10 +29,11 @@ from taxonomy.choices import ProductTypes from taxonomy.utils import get_whitelisted_serialized_skills +from course_discovery.apps.api.cache import get_utm_source_request_cache_key from course_discovery.apps.api.fields import ( HtmlField, ImageField, SlugRelatedFieldWithReadSerializer, SlugRelatedTranslatableField, StdImageSerializerField ) -from course_discovery.apps.api.utils import StudioAPI, get_excluded_restriction_types +from course_discovery.apps.api.utils import StudioAPI, get_excluded_restriction_types, use_request_cache from course_discovery.apps.catalogs.models import Catalog from course_discovery.apps.core.api_client.lms import LMSAPIClient from course_discovery.apps.core.utils import update_instance @@ -146,7 +148,7 @@ def get_lms_course_url_for_archived(partner, course_key): return f'{lms_url}/courses/{course_key}/course/' - +@use_request_cache("utm_source_cache", get_utm_source_request_cache_key) def get_utm_source_for_user(partner, user): """ Return the utm source for the user. diff --git a/course_discovery/apps/api/utils.py b/course_discovery/apps/api/utils.py index 1818ef62d9..afcc976e49 100644 --- a/course_discovery/apps/api/utils.py +++ b/course_discovery/apps/api/utils.py @@ -7,6 +7,7 @@ from django.core.files.base import ContentFile from django.db.models.fields.related import ManyToManyField from django.utils.translation import gettext as _ +from edx_django_utils.cache import RequestCache, get_cache_key from opaque_keys.edx.keys import CourseKey from requests.exceptions import HTTPError from sortedm2m.fields import SortedManyToManyField @@ -352,3 +353,20 @@ def push_to_studio(self, course_run, create=False, old_course_run_key=None, user self.create_course_run_in_studio(course_run, user=user) else: self.update_course_run_details_in_studio(course_run) + +def use_request_cache(cache_name, key_func): + def inner(fn): + @functools.wraps(fn) + def foo(*args, **kwargs): + cache = RequestCache(cache_name) + cache_key = key_func(*args, **kwargs) + cached_response = cache.get_cached_response(cache_key) + if cached_response.is_found: + return cached_response.value + + ret_val = fn(*args, **kwargs) + + cache.set(cache_key, ret_val) + return ret_val + return foo + return inner