Revert "ARCH-223: Retire deprecated RequestCache."

This commit is contained in:
Nimisha Asthagiri
2018-08-30 15:04:10 -04:00
committed by Alex Dusenbery
parent 8459982512
commit 4ca165f690
32 changed files with 170 additions and 103 deletions

View File

@@ -4,8 +4,8 @@ Bookmarks service.
import logging
from django.core.exceptions import ObjectDoesNotExist
from edx_django_utils.cache import DEFAULT_REQUEST_CACHE
from openedx.core.djangoapps.request_cache.middleware import RequestCache
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError
@@ -46,12 +46,12 @@ class BookmarksService(object):
return []
cache_key = CACHE_KEY_TEMPLATE.format(self._user.id, course_key)
bookmarks_cache = DEFAULT_REQUEST_CACHE.data.get(cache_key, None)
bookmarks_cache = RequestCache.get_request_cache().data.get(cache_key, None)
if bookmarks_cache is None and fetch is True:
bookmarks_cache = api.get_bookmarks(
self._user, course_key=course_key, fields=DEFAULT_FIELDS
)
DEFAULT_REQUEST_CACHE.data[cache_key] = bookmarks_cache
RequestCache.get_request_cache().data[cache_key] = bookmarks_cache
return bookmarks_cache

View File

@@ -9,10 +9,10 @@ import logging
from celery import task
from django.conf import settings
from django.utils import six, timezone
from edx_django_utils.cache import RequestCache
from opaque_keys.edx.keys import CourseKey
from py2neo import Graph, Node, Relationship, authenticate, NodeSelector
from py2neo.compat import integer, string, unicode as neo4j_unicode
from openedx.core.djangoapps.request_cache.middleware import RequestCache
log = logging.getLogger(__name__)
@@ -348,7 +348,7 @@ class ModuleStoreSerializer(object):
for index, course_key in enumerate(self.course_keys):
# first, clear the request cache to prevent memory leaks
RequestCache.clear_all_namespaces()
RequestCache.clear_request_cache()
log.info(
"Now submitting %s for export to neo4j: course %d of %d total courses",

View File

@@ -19,12 +19,12 @@ from django.db import IntegrityError, models, transaction
from django.dispatch import receiver
from django.utils.translation import ugettext as _
from django.utils.translation import ugettext_lazy
from edx_django_utils.cache import RequestCache
from jsonfield.fields import JSONField
from model_utils.models import TimeStampedModel
from opaque_keys.edx.django.models import CourseKeyField
from openedx.core.djangoapps.request_cache.middleware import ns_request_cached
from openedx.core.djangoapps.request_cache.middleware import RequestCache, ns_request_cached
from student.models import get_retired_username_by_username
CREDIT_PROVIDER_ID_REGEX = r"[a-z,A-Z,0-9,\-]+"
log = logging.getLogger(__name__)
@@ -401,7 +401,7 @@ class CreditRequirement(TimeStampedModel):
@receiver(models.signals.post_delete, sender=CreditRequirement)
def invalidate_credit_requirement_cache(sender, **kwargs): # pylint: disable=unused-argument
"""Invalidate the cache of credit requirements. """
RequestCache(namespace=CreditRequirement.CACHE_NAMESPACE).clear()
RequestCache.clear_request_cache(name=CreditRequirement.CACHE_NAMESPACE)
class CreditRequirementStatus(TimeStampedModel):

View File

@@ -12,7 +12,6 @@ from celery.signals import task_postrun
import crum
from django.conf import settings
from django.test.client import RequestFactory
from edx_django_utils.cache import RequestCache
from openedx.core.djangoapps.request_cache import middleware
@@ -27,7 +26,7 @@ def clear_request_cache(**kwargs): # pylint: disable=unused-argument
prevent memory leaks.
"""
if getattr(settings, 'CLEAR_REQUEST_CACHE_ON_TASK_COMPLETION', True):
RequestCache.clear_all_namespaces()
middleware.RequestCache.clear_request_cache()
def get_cache(name):
@@ -39,8 +38,7 @@ def get_cache(name):
Returns: dict
"""
assert name is not None
return RequestCache(name).data
return middleware.RequestCache.get_request_cache(name)
def clear_cache(name):
@@ -50,7 +48,16 @@ def clear_cache(name):
Arguments:
name (str): The name of the request cache to clear
"""
RequestCache(name).clear()
return middleware.RequestCache.clear_request_cache(name)
def get_request():
"""
Return the current request.
Deprecated: Please use crum to retrieve current requests.
"""
return crum.get_current_request()
def get_request_or_stub():

View File

@@ -1,12 +1,67 @@
"""
The middleware for the edx-platform version of the RequestCache has been
removed in favor of the RequestCache found in edx-django-utils.
An implementation of a RequestCache. This cache is reset at the beginning
and end of every request.
"""
import threading
TODO: This file still contains request cache related decorators that
should be moved out of this middleware file.
"""
import crum
from django.utils.encoding import force_text
from edx_django_utils.cache import RequestCache
class _RequestCache(threading.local):
"""
A thread-local for storing the per-request cache.
"""
def __init__(self):
super(_RequestCache, self).__init__()
self.data = {}
REQUEST_CACHE = _RequestCache()
class RequestCache(object):
@classmethod
def get_request_cache(cls, name=None):
"""
This method is deprecated. Please use :func:`request_cache.get_cache`.
"""
if name is None:
return REQUEST_CACHE
else:
return REQUEST_CACHE.data.setdefault(name, {})
@classmethod
def get_current_request(cls):
"""
This method is deprecated. Please use :func:`request_cache.get_request`.
"""
return crum.get_current_request()
@classmethod
def clear_request_cache(cls, name=None):
"""
Empty the request cache.
"""
if name is None:
REQUEST_CACHE.data = {}
elif REQUEST_CACHE.data.get(name):
REQUEST_CACHE.data[name] = {}
def process_request(self, request):
self.clear_request_cache()
return None
def process_response(self, request, response):
self.clear_request_cache()
return response
def process_exception(self, request, exception): # pylint: disable=unused-argument
"""
Clear the RequestCache after a failed request.
"""
self.clear_request_cache()
return None
def request_cached(f):
@@ -39,8 +94,7 @@ def ns_request_cached(namespace=None):
Arguments:
namespace (string): An optional namespace to use for the cache. Useful if the caller wants to manage
their own sub-cache by, for example, calling RequestCache(namespace=NAMESPACE).clear() for their own
namespace.
their own sub-cache by, for example, calling RequestCache.clear_request_cache for their own namespace.
"""
def outer_wrapper(f):
"""
@@ -55,22 +109,22 @@ def ns_request_cached(namespace=None):
"""
# Check to see if we have a result in cache. If not, invoke our wrapped
# function. Cache and return the result to the caller.
request_cache = RequestCache(namespace)
cache_key = _func_call_cache_key(f, *args, **kwargs)
rcache = RequestCache.get_request_cache(namespace)
rcache = rcache.data if namespace is None else rcache
cache_key = func_call_cache_key(f, *args, **kwargs)
cached_response = request_cache.get_cached_response(cache_key)
if cached_response.is_found:
return cached_response.value
result = f(*args, **kwargs)
request_cache.set(cache_key, result)
return result
if cache_key in rcache:
return rcache.get(cache_key)
else:
result = f(*args, **kwargs)
rcache[cache_key] = result
return result
return inner_wrapper
return outer_wrapper
def _func_call_cache_key(func, *args, **kwargs):
def func_call_cache_key(func, *args, **kwargs):
"""
Returns a cache key based on the function's module
the function's name, and a stringified list of arguments

View File

@@ -6,17 +6,16 @@ from celery.task import task
from django.conf import settings
from django.test import TestCase
from django.test.utils import override_settings
from edx_django_utils.cache import RequestCache
from mock import Mock
from openedx.core.djangoapps.request_cache import get_request_or_stub
from openedx.core.djangoapps.request_cache.middleware import request_cached
from openedx.core.djangoapps.request_cache.middleware import RequestCache, request_cached
from xmodule.modulestore.django import modulestore
class TestRequestCache(TestCase):
"""
Tests for request cache helpers and decorators.
Tests for the request cache.
"""
def test_get_request_or_stub(self):
@@ -44,7 +43,7 @@ class TestRequestCache(TestCase):
"""
Ensure that after a cache miss, we fill the cache and can hit it.
"""
RequestCache.clear_all_namespaces()
RequestCache.clear_request_cache()
to_be_wrapped = Mock()
to_be_wrapped.return_value = 42
@@ -67,7 +66,7 @@ class TestRequestCache(TestCase):
"""
Ensure that after caching a result, we always send it back, even if the underlying result changes.
"""
RequestCache.clear_all_namespaces()
RequestCache.clear_request_cache()
to_be_wrapped = Mock()
to_be_wrapped.side_effect = [1, 2, 3]
@@ -103,7 +102,7 @@ class TestRequestCache(TestCase):
Ensure that calling a decorated function with different positional arguments
will not use a cached value invoked by a previous call with different arguments.
"""
RequestCache.clear_all_namespaces()
RequestCache.clear_request_cache()
to_be_wrapped = Mock()
to_be_wrapped.side_effect = [1, 2, 3, 4, 5, 6]
@@ -144,7 +143,7 @@ class TestRequestCache(TestCase):
Ensure that calling a decorated function with different keyword arguments
will not use a cached value invoked by a previous call with different arguments.
"""
RequestCache.clear_all_namespaces()
RequestCache.clear_request_cache()
to_be_wrapped = Mock()
to_be_wrapped.side_effect = [1, 2, 3, 4, 5, 6]
@@ -189,7 +188,7 @@ class TestRequestCache(TestCase):
"""
Ensure that request_cached can work with mixed str and Unicode parameters.
"""
RequestCache.clear_all_namespaces()
RequestCache.clear_request_cache()
def dummy_function(arg1, arg2):
"""
@@ -213,7 +212,7 @@ class TestRequestCache(TestCase):
properly caches the result and doesn't recall the underlying
function.
"""
RequestCache.clear_all_namespaces()
RequestCache.clear_request_cache()
to_be_wrapped = Mock()
to_be_wrapped.side_effect = [None, None, None, 1, 1]

View File

@@ -8,7 +8,6 @@ import os
import re
from logging import getLogger
import crum
from django.conf import settings
from microsite_configuration import microsite
@@ -20,7 +19,7 @@ from openedx.core.djangoapps.theming.helpers_dirs import (
get_theme_dirs,
get_themes_unchecked
)
from openedx.core.djangoapps.request_cache.middleware import request_cached
from openedx.core.djangoapps.request_cache.middleware import RequestCache, request_cached
logger = getLogger(__name__) # pylint: disable=invalid-name
@@ -166,7 +165,7 @@ def get_current_request():
Returns:
(HttpRequest): returns current request
"""
return crum.get_current_request()
return RequestCache.get_current_request()
def get_current_site():

View File

@@ -5,7 +5,6 @@ from mock import patch, Mock
from django.test import TestCase, override_settings
from django.conf import settings
from edx_django_utils.cache import RequestCache
from openedx.core.djangoapps.theming.tests.test_util import with_comprehensive_theme
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
@@ -13,6 +12,7 @@ from openedx.core.djangoapps.theming import helpers as theming_helpers
from openedx.core.djangoapps.theming.helpers import get_template_path_with_theme, strip_site_theme_templates_path, \
get_themes, Theme, get_theme_base_dir
from openedx.core.djangolib.testing.utils import skip_unless_cms, skip_unless_lms
from openedx.core.djangoapps.request_cache.middleware import RequestCache
class TestHelpers(TestCase):
@@ -190,7 +190,7 @@ class TestHelpers(TestCase):
mock_microsite_backend.get_template = Mock(return_value="/microsite/about.html")
self.assertEqual(theming_helpers.get_template_path("about.html"), "about.html")
RequestCache.clear_all_namespaces()
RequestCache.clear_request_cache()
# if the current site does not have associated SiteTheme then get_template_path should return microsite override
with patch(

View File

@@ -8,7 +8,6 @@ from django.db import models
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
from django.utils.translation import ugettext_lazy
from edx_django_utils.cache import RequestCache
from opaque_keys.edx.django.models import CourseKeyField
from lms.djangoapps.courseware.courses import get_course_by_id
@@ -19,7 +18,7 @@ from openedx.core.djangoapps.course_groups.cohorts import (
is_course_cohorted
)
from openedx.core.djangoapps.verified_track_content.tasks import sync_cohort_with_mode
from openedx.core.djangoapps.request_cache.middleware import ns_request_cached
from openedx.core.djangoapps.request_cache.middleware import RequestCache, ns_request_cached
from student.models import CourseEnrollment
log = logging.getLogger(__name__)
@@ -148,7 +147,7 @@ class VerifiedTrackCohortedCourse(models.Model):
@receiver(models.signals.post_delete, sender=VerifiedTrackCohortedCourse)
def invalidate_verified_track_cache(sender, **kwargs): # pylint: disable=unused-argument
"""Invalidate the cache of VerifiedTrackCohortedCourse. """
RequestCache(namespace=VerifiedTrackCohortedCourse.CACHE_NAMESPACE).clear()
RequestCache.clear_request_cache(name=VerifiedTrackCohortedCourse.CACHE_NAMESPACE)
class MigrateVerifiedTrackCohortsSetting(ConfigurationModel):

View File

@@ -5,9 +5,9 @@ import crum
import ddt
from django.test import TestCase
from django.test.client import RequestFactory
from edx_django_utils.cache import RequestCache
from mock import patch
from opaque_keys.edx.keys import CourseKey
from openedx.core.djangoapps.request_cache.middleware import RequestCache
from waffle.testutils import override_flag
from .. import CourseWaffleFlag, WaffleFlagNamespace, WaffleSwitchNamespace, WaffleSwitch
@@ -34,7 +34,7 @@ class TestCourseWaffleFlag(TestCase):
request = RequestFactory().request()
self.addCleanup(crum.set_current_request, None)
crum.set_current_request(request)
RequestCache.clear_all_namespaces()
RequestCache.clear_request_cache()
@ddt.data(
{'course_override': WaffleFlagCourseOverrideModel.ALL_CHOICES.on, 'waffle_enabled': False, 'result': True},

View File

@@ -3,9 +3,10 @@ Tests for waffle utils models.
"""
from ddt import data, ddt, unpack
from django.test import TestCase
from edx_django_utils.cache import RequestCache
from opaque_keys.edx.keys import CourseKey
from openedx.core.djangoapps.request_cache.middleware import RequestCache
from ..models import WaffleFlagCourseOverrideModel
@@ -25,7 +26,7 @@ class WaffleFlagCourseOverrideTests(TestCase):
(False, OVERRIDE_CHOICES.on, OVERRIDE_CHOICES.unset))
@unpack
def test_setting_override(self, is_enabled, override_choice, expected_result):
RequestCache.clear_all_namespaces()
RequestCache.clear_request_cache()
self.set_waffle_course_override(override_choice, is_enabled)
override_value = WaffleFlagCourseOverrideModel.override_value(
self.WAFFLE_TEST_NAME, self.TEST_COURSE_KEY
@@ -33,7 +34,7 @@ class WaffleFlagCourseOverrideTests(TestCase):
self.assertEqual(override_value, expected_result)
def test_setting_override_multiple_times(self):
RequestCache.clear_all_namespaces()
RequestCache.clear_request_cache()
self.set_waffle_course_override(self.OVERRIDE_CHOICES.on)
self.set_waffle_course_override(self.OVERRIDE_CHOICES.off)
override_value = WaffleFlagCourseOverrideModel.override_value(

View File

@@ -5,9 +5,9 @@ Tests for waffle utils test utilities.
import crum
from django.test import TestCase
from django.test.client import RequestFactory
from edx_django_utils.cache import RequestCache
from opaque_keys.edx.keys import CourseKey
from openedx.core.djangoapps.request_cache.middleware import RequestCache
from .. import CourseWaffleFlag, WaffleFlagNamespace
from ..testutils import override_waffle_flag
@@ -30,7 +30,7 @@ class OverrideWaffleFlagTests(TestCase):
request = RequestFactory().request()
self.addCleanup(crum.set_current_request, None)
crum.set_current_request(request)
RequestCache.clear_all_namespaces()
RequestCache.clear_request_cache()
@override_waffle_flag(TEST_COURSE_FLAG, True)
def assert_decorator_activates_flag(self):