Merge pull request #26017 from regisb/regisb/refactor_set_request_cache
[BD-21] Get rid of calls to `set_request_cache_with_short_name`
This commit is contained in:
@@ -17,7 +17,7 @@ from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import SampleCourseFactory, check_mongo_calls
|
||||
from xmodule.modulestore.tests.sample_courses import BlockInfo
|
||||
from openedx.core.djangoapps.content.block_structure.api import clear_course_from_cache
|
||||
from openedx.core.djangoapps.content.block_structure.config import STORAGE_BACKING_FOR_CACHE, waffle_switch
|
||||
from openedx.core.djangoapps.content.block_structure.config import STORAGE_BACKING_FOR_CACHE
|
||||
|
||||
from ..api import get_blocks
|
||||
|
||||
@@ -230,7 +230,7 @@ class TestGetBlocksQueryCounts(TestGetBlocksQueryCountsBase):
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_query_counts_cached(self, store_type, with_storage_backing):
|
||||
with override_waffle_switch(waffle_switch(STORAGE_BACKING_FOR_CACHE), active=with_storage_backing):
|
||||
with override_waffle_switch(STORAGE_BACKING_FOR_CACHE, active=with_storage_backing):
|
||||
course = self._create_course(store_type)
|
||||
self._get_blocks(
|
||||
course,
|
||||
@@ -247,7 +247,7 @@ class TestGetBlocksQueryCounts(TestGetBlocksQueryCountsBase):
|
||||
@ddt.unpack
|
||||
def test_query_counts_uncached(self, store_type_tuple, with_storage_backing):
|
||||
store_type, expected_mongo_queries = store_type_tuple
|
||||
with override_waffle_switch(waffle_switch(STORAGE_BACKING_FOR_CACHE), active=with_storage_backing):
|
||||
with override_waffle_switch(STORAGE_BACKING_FOR_CACHE, active=with_storage_backing):
|
||||
course = self._create_course(store_type)
|
||||
clear_course_from_cache(course.id)
|
||||
|
||||
|
||||
@@ -2,37 +2,32 @@
|
||||
This module contains various configuration settings via
|
||||
waffle switches for the Block Structure framework.
|
||||
"""
|
||||
from edx_django_utils.cache import RequestCache
|
||||
from edx_toggles.toggles.__future__ import WaffleSwitch
|
||||
|
||||
|
||||
from edx_toggles.toggles import LegacyWaffleSwitch, LegacyWaffleSwitchNamespace
|
||||
from openedx.core.lib.cache_utils import request_cached
|
||||
|
||||
from .models import BlockStructureConfiguration
|
||||
|
||||
# Namespace
|
||||
WAFFLE_NAMESPACE = u'block_structure'
|
||||
|
||||
# Switches
|
||||
INVALIDATE_CACHE_ON_PUBLISH = u'invalidate_cache_on_publish'
|
||||
STORAGE_BACKING_FOR_CACHE = u'storage_backing_for_cache'
|
||||
RAISE_ERROR_WHEN_NOT_FOUND = u'raise_error_when_not_found'
|
||||
INVALIDATE_CACHE_ON_PUBLISH = WaffleSwitch(
|
||||
"block_structure.invalidate_cache_on_publish", __name__
|
||||
)
|
||||
STORAGE_BACKING_FOR_CACHE = WaffleSwitch(
|
||||
"block_structure.storage_backing_for_cache", __name__
|
||||
)
|
||||
RAISE_ERROR_WHEN_NOT_FOUND = WaffleSwitch(
|
||||
"block_structure.raise_error_when_not_found", __name__
|
||||
)
|
||||
|
||||
|
||||
def waffle():
|
||||
def enable_storage_backing_for_cache_in_request():
|
||||
"""
|
||||
Returns the namespaced and cached Waffle class for BlockStructures.
|
||||
Manually override the value of the STORAGE_BACKING_FOR_CACHE switch in the context of the request.
|
||||
This function should not be replicated, as it accesses a protected member, and it shouldn't.
|
||||
"""
|
||||
return LegacyWaffleSwitchNamespace(name=WAFFLE_NAMESPACE, log_prefix=u'BlockStructure: ')
|
||||
|
||||
|
||||
def waffle_switch(name):
|
||||
"""
|
||||
Return the waffle switch associated to this namespace.
|
||||
|
||||
WARNING: do not replicate this pattern. Instead of declaring waffle switch names as strings, you should create
|
||||
LegacyWaffleSwitch objects as top-level constants.
|
||||
"""
|
||||
return LegacyWaffleSwitch(waffle(), name, module_name=__name__)
|
||||
# pylint: disable=protected-access
|
||||
STORAGE_BACKING_FOR_CACHE._cached_switches[STORAGE_BACKING_FOR_CACHE.name] = True
|
||||
|
||||
|
||||
@request_cached()
|
||||
|
||||
@@ -7,13 +7,12 @@ import logging
|
||||
|
||||
import six
|
||||
from django.core.management.base import BaseCommand
|
||||
import six
|
||||
from six import text_type
|
||||
|
||||
import openedx.core.djangoapps.content.block_structure.api as api
|
||||
import openedx.core.djangoapps.content.block_structure.store as store
|
||||
import openedx.core.djangoapps.content.block_structure.tasks as tasks
|
||||
from openedx.core.djangoapps.content.block_structure.config import STORAGE_BACKING_FOR_CACHE, waffle
|
||||
from openedx.core.djangoapps.content.block_structure.config import enable_storage_backing_for_cache_in_request
|
||||
from openedx.core.lib.command_utils import (
|
||||
get_mutually_exclusive_required_option,
|
||||
parse_course_keys,
|
||||
@@ -133,7 +132,7 @@ class Command(BaseCommand):
|
||||
Generates course blocks for the given course_keys per the given options.
|
||||
"""
|
||||
if options.get('with_storage'):
|
||||
waffle().set_request_cache_with_short_name(STORAGE_BACKING_FOR_CACHE, True)
|
||||
enable_storage_backing_for_cache_in_request()
|
||||
|
||||
for course_key in course_keys:
|
||||
try:
|
||||
|
||||
@@ -102,10 +102,9 @@ class BlockStructureManager(object):
|
||||
BlockStructureTransformers.verify_versions(block_structure)
|
||||
|
||||
except (BlockStructureNotFound, TransformerDataIncompatible):
|
||||
if config.waffle().is_enabled(config.RAISE_ERROR_WHEN_NOT_FOUND):
|
||||
if config.RAISE_ERROR_WHEN_NOT_FOUND.is_enabled():
|
||||
raise
|
||||
else:
|
||||
block_structure = self._update_collected()
|
||||
block_structure = self._update_collected()
|
||||
|
||||
return block_structure
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ def update_block_structure_on_course_publish(sender, course_key, **kwargs): # p
|
||||
if isinstance(course_key, LibraryLocator):
|
||||
return
|
||||
|
||||
if config.waffle().is_enabled(config.INVALIDATE_CACHE_ON_PUBLISH):
|
||||
if config.INVALIDATE_CACHE_ON_PUBLISH.is_enabled():
|
||||
try:
|
||||
clear_course_from_cache(course_key)
|
||||
except BlockStructureNotFound:
|
||||
|
||||
@@ -7,8 +7,8 @@ Module for the Storage of BlockStructure objects.
|
||||
from logging import getLogger
|
||||
|
||||
import six
|
||||
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
|
||||
from openedx.core.lib.cache_utils import zpickle, zunpickle
|
||||
|
||||
from . import config
|
||||
@@ -28,6 +28,7 @@ class StubModel(object):
|
||||
By using this stub, we eliminate the need for extra
|
||||
conditional statements in the code.
|
||||
"""
|
||||
|
||||
def __init__(self, root_block_usage_key):
|
||||
self.data_usage_key = root_block_usage_key
|
||||
|
||||
@@ -45,6 +46,7 @@ class BlockStructureStore(object):
|
||||
"""
|
||||
Storage for BlockStructure objects.
|
||||
"""
|
||||
|
||||
def __init__(self, cache):
|
||||
"""
|
||||
Arguments:
|
||||
@@ -121,7 +123,7 @@ class BlockStructureStore(object):
|
||||
Returns whether the data in storage for the given key is
|
||||
already up-to-date with the version in the given modulestore.
|
||||
"""
|
||||
if _is_storage_backing_enabled():
|
||||
if config.STORAGE_BACKING_FOR_CACHE.is_enabled():
|
||||
try:
|
||||
bs_model = self._get_model(root_block_usage_key)
|
||||
root_block = modulestore.get_item(root_block_usage_key)
|
||||
@@ -135,7 +137,7 @@ class BlockStructureStore(object):
|
||||
"""
|
||||
Returns the model associated with the given key.
|
||||
"""
|
||||
if _is_storage_backing_enabled():
|
||||
if config.STORAGE_BACKING_FOR_CACHE.is_enabled():
|
||||
return BlockStructureModel.get(root_block_usage_key)
|
||||
else:
|
||||
return StubModel(root_block_usage_key)
|
||||
@@ -145,7 +147,7 @@ class BlockStructureStore(object):
|
||||
Updates or creates the model for the given block_structure
|
||||
and serialized_data.
|
||||
"""
|
||||
if _is_storage_backing_enabled():
|
||||
if config.STORAGE_BACKING_FOR_CACHE.is_enabled():
|
||||
root_block = block_structure[block_structure.root_block_usage_key]
|
||||
bs_model, _ = BlockStructureModel.update_or_create(
|
||||
serialized_data,
|
||||
@@ -187,7 +189,7 @@ class BlockStructureStore(object):
|
||||
Raises:
|
||||
BlockStructureNotFound if not found.
|
||||
"""
|
||||
if not _is_storage_backing_enabled():
|
||||
if not config.STORAGE_BACKING_FOR_CACHE.is_enabled():
|
||||
raise BlockStructureNotFound(bs_model.data_usage_key)
|
||||
|
||||
return bs_model.get_serialized_data()
|
||||
@@ -229,14 +231,12 @@ class BlockStructureStore(object):
|
||||
Returns the cache key to use for the given
|
||||
BlockStructureModel or StubModel.
|
||||
"""
|
||||
if _is_storage_backing_enabled():
|
||||
if config.STORAGE_BACKING_FOR_CACHE.is_enabled():
|
||||
return six.text_type(bs_model)
|
||||
|
||||
else:
|
||||
return "v{version}.root.key.{root_usage_key}".format(
|
||||
version=six.text_type(BlockStructureBlockData.VERSION),
|
||||
root_usage_key=six.text_type(bs_model.data_usage_key),
|
||||
)
|
||||
return "v{version}.root.key.{root_usage_key}".format(
|
||||
version=six.text_type(BlockStructureBlockData.VERSION),
|
||||
root_usage_key=six.text_type(bs_model.data_usage_key),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _version_data_of_block(root_block):
|
||||
@@ -260,10 +260,3 @@ class BlockStructureStore(object):
|
||||
field_name: getattr(bs_model, field_name, None)
|
||||
for field_name in BlockStructureModel.VERSION_FIELDS
|
||||
}
|
||||
|
||||
|
||||
def _is_storage_backing_enabled():
|
||||
"""
|
||||
Returns whether storage backing for Block Structures is enabled.
|
||||
"""
|
||||
return config.waffle().is_enabled(config.STORAGE_BACKING_FOR_CACHE)
|
||||
|
||||
@@ -14,7 +14,7 @@ from opaque_keys.edx.keys import CourseKey
|
||||
|
||||
from capa.responsetypes import LoncapaProblemError
|
||||
from openedx.core.djangoapps.content.block_structure import api
|
||||
from openedx.core.djangoapps.content.block_structure.config import STORAGE_BACKING_FOR_CACHE, waffle
|
||||
from openedx.core.djangoapps.content.block_structure.config import enable_storage_backing_for_cache_in_request
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
|
||||
log = logging.getLogger('edx.celery.task')
|
||||
@@ -63,7 +63,7 @@ def _update_course_in_cache(self, **kwargs):
|
||||
Updates the course blocks (mongo -> BlockStructure) for the specified course.
|
||||
"""
|
||||
if kwargs.get('with_storage'):
|
||||
waffle().set_request_cache_with_short_name(STORAGE_BACKING_FOR_CACHE, True)
|
||||
enable_storage_backing_for_cache_in_request()
|
||||
_call_and_retry_if_needed(self, api.update_course_in_cache, **kwargs)
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ def _get_course_in_cache(self, **kwargs):
|
||||
Gets the course blocks for the specified course, updating the cache if needed.
|
||||
"""
|
||||
if kwargs.get('with_storage'):
|
||||
waffle().set_request_cache_with_short_name(STORAGE_BACKING_FOR_CACHE, True)
|
||||
enable_storage_backing_for_cache_in_request()
|
||||
_call_and_retry_if_needed(self, api.get_course_in_cache, **kwargs)
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ from django.test import TestCase
|
||||
from edx_toggles.toggles.testutils import override_waffle_switch
|
||||
|
||||
from ..block_structure import BlockStructureBlockData
|
||||
from ..config import RAISE_ERROR_WHEN_NOT_FOUND, STORAGE_BACKING_FOR_CACHE, waffle_switch
|
||||
from ..config import RAISE_ERROR_WHEN_NOT_FOUND, STORAGE_BACKING_FOR_CACHE
|
||||
from ..exceptions import BlockStructureNotFound, UsageKeyNotInBlockStructure
|
||||
from ..manager import BlockStructureManager
|
||||
from ..transformers import BlockStructureTransformers
|
||||
@@ -179,14 +179,14 @@ class TestBlockStructureManager(UsageKeyFactoryMixin, ChildrenMapTestMixin, Test
|
||||
assert TestTransformer1.collect_call_count == 1
|
||||
|
||||
def test_get_collected_error_raised(self):
|
||||
with override_waffle_switch(waffle_switch(RAISE_ERROR_WHEN_NOT_FOUND), active=True):
|
||||
with override_waffle_switch(RAISE_ERROR_WHEN_NOT_FOUND, active=True):
|
||||
with mock_registered_transformers(self.registered_transformers):
|
||||
with self.assertRaises(BlockStructureNotFound):
|
||||
self.bs_manager.get_collected()
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_update_collected_if_needed(self, with_storage_backing):
|
||||
with override_waffle_switch(waffle_switch(STORAGE_BACKING_FOR_CACHE), active=with_storage_backing):
|
||||
with override_waffle_switch(STORAGE_BACKING_FOR_CACHE, active=with_storage_backing):
|
||||
with mock_registered_transformers(self.registered_transformers):
|
||||
assert TestTransformer1.collect_call_count == 0
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
|
||||
from ..api import get_block_structure_manager
|
||||
from ..config import INVALIDATE_CACHE_ON_PUBLISH, waffle_switch
|
||||
from ..config import INVALIDATE_CACHE_ON_PUBLISH
|
||||
from ..signals import update_block_structure_on_course_publish
|
||||
from .helpers import is_course_in_block_structure_cache
|
||||
|
||||
@@ -56,7 +56,7 @@ class CourseBlocksSignalTest(ModuleStoreTestCase):
|
||||
def test_cache_invalidation(self, invalidate_cache_enabled, mock_bs_manager_clear):
|
||||
test_display_name = "Jedi 101"
|
||||
|
||||
with override_waffle_switch(waffle_switch(INVALIDATE_CACHE_ON_PUBLISH), active=invalidate_cache_enabled):
|
||||
with override_waffle_switch(INVALIDATE_CACHE_ON_PUBLISH, active=invalidate_cache_enabled):
|
||||
self.course.display_name = test_display_name
|
||||
self.store.update_item(self.course, self.user.id)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from edx_toggles.toggles.testutils import override_waffle_switch
|
||||
|
||||
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
|
||||
|
||||
from ..config import STORAGE_BACKING_FOR_CACHE, waffle_switch
|
||||
from ..config import STORAGE_BACKING_FOR_CACHE
|
||||
from ..config.models import BlockStructureConfiguration
|
||||
from ..exceptions import BlockStructureNotFound
|
||||
from ..store import BlockStructureStore
|
||||
@@ -48,13 +48,13 @@ class TestBlockStructureStore(UsageKeyFactoryMixin, ChildrenMapTestMixin, CacheI
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_get_none(self, with_storage_backing):
|
||||
with override_waffle_switch(waffle_switch(STORAGE_BACKING_FOR_CACHE), active=with_storage_backing):
|
||||
with override_waffle_switch(STORAGE_BACKING_FOR_CACHE, active=with_storage_backing):
|
||||
with self.assertRaises(BlockStructureNotFound):
|
||||
self.store.get(self.block_structure.root_block_usage_key)
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_add_and_get(self, with_storage_backing):
|
||||
with override_waffle_switch(waffle_switch(STORAGE_BACKING_FOR_CACHE), active=with_storage_backing):
|
||||
with override_waffle_switch(STORAGE_BACKING_FOR_CACHE, active=with_storage_backing):
|
||||
self.store.add(self.block_structure)
|
||||
stored_value = self.store.get(self.block_structure.root_block_usage_key)
|
||||
self.assertIsNotNone(stored_value)
|
||||
@@ -62,7 +62,7 @@ class TestBlockStructureStore(UsageKeyFactoryMixin, ChildrenMapTestMixin, CacheI
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_delete(self, with_storage_backing):
|
||||
with override_waffle_switch(waffle_switch(STORAGE_BACKING_FOR_CACHE), active=with_storage_backing):
|
||||
with override_waffle_switch(STORAGE_BACKING_FOR_CACHE, active=with_storage_backing):
|
||||
self.store.add(self.block_structure)
|
||||
self.store.delete(self.block_structure.root_block_usage_key)
|
||||
with self.assertRaises(BlockStructureNotFound):
|
||||
@@ -75,7 +75,7 @@ class TestBlockStructureStore(UsageKeyFactoryMixin, ChildrenMapTestMixin, CacheI
|
||||
self.store.get(self.block_structure.root_block_usage_key)
|
||||
|
||||
def test_uncached_with_storage(self):
|
||||
with override_waffle_switch(waffle_switch(STORAGE_BACKING_FOR_CACHE), active=True):
|
||||
with override_waffle_switch(STORAGE_BACKING_FOR_CACHE, active=True):
|
||||
self.store.add(self.block_structure)
|
||||
self.mock_cache.map.clear()
|
||||
stored_value = self.store.get(self.block_structure.root_block_usage_key)
|
||||
|
||||
@@ -500,9 +500,7 @@ class TestModuleStoreSerializer(TestDumpToNeo4jCommandBase):
|
||||
self.assertEqual(len(submitted), len(self.course_strings))
|
||||
|
||||
# simulate one of the courses being published
|
||||
with override_waffle_switch(
|
||||
block_structure_config.waffle_switch(block_structure_config.STORAGE_BACKING_FOR_CACHE), True
|
||||
):
|
||||
with override_waffle_switch(block_structure_config.STORAGE_BACKING_FOR_CACHE, True):
|
||||
update_block_structure_on_course_publish(None, self.course.id)
|
||||
|
||||
# make sure only the published course was dumped
|
||||
|
||||
Reference in New Issue
Block a user