Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: [AXIMST-806] returned cache clearing when publishing a course #2544

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cms/djangoapps/contentstore/signals/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
CoursewareSearchIndexer,
LibrarySearchIndexer,
)
from cms.djangoapps.contentstore.utils import drop_course_sidebar_blocks_cache
from common.djangoapps.track.event_transaction_utils import get_event_transaction_id, get_event_transaction_type
from common.djangoapps.util.block_utils import yield_dynamic_block_descendants
from lms.djangoapps.grades.api import task_compute_all_grades_for_course
Expand Down Expand Up @@ -141,6 +142,7 @@ def listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable=
# register special exams asynchronously after the data is ready
course_key_str = str(course_key)
transaction.on_commit(lambda: update_special_exams_and_publish.delay(course_key_str))
drop_course_sidebar_blocks_cache(course_key_str)

if key_supports_outlines(course_key):
# Push the course outline to learning_sequences asynchronously.
Expand Down
36 changes: 35 additions & 1 deletion cms/djangoapps/contentstore/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
from collections import defaultdict
from contextlib import contextmanager
from datetime import datetime, timezone
from urllib.parse import quote_plus
from urllib.parse import quote_plus, unquote
from uuid import uuid4

from django.conf import settings
from django.core.cache import cache
from django.core.exceptions import ValidationError
from django.urls import reverse
from django.utils import translation
Expand Down Expand Up @@ -2287,3 +2288,36 @@ def get_xblock_render_context(request, block):
return str(exc)

return ""


def drop_course_sidebar_blocks_cache(course_id: str):
"""
Drop the course sidebar blocks cache for the given course.
"""
cache_key_prefix = f"course_sidebar_blocks_{course_id}"
cache_keys = get_cache_keys(cache_key_prefix)

cache.delete_many(cache_keys)


def get_cache_keys(cache_key_prefix):
"""
Get all cache keys for the given cache key prefix.
LocMemCache does not have a keys method, so we need to iterate over the cache
and manually filter out the keys that match the given prefix.
"""
cache_backend = settings.CACHES['default']['BACKEND']
if cache_backend == 'django_redis.cache.RedisCache':
yield cache.iter_keys(f"{cache_key_prefix}*")
elif cache_backend == 'django.core.cache.backends.locmem.LocMemCache':
for key in cache._cache.keys(): # pylint: disable=protected-access
try:
decoded_key = unquote(key.split(':', 2)[-1], encoding='utf-8')
except IndexError:
continue

if decoded_key.startswith(cache_key_prefix):
yield decoded_key
else:
log.error(f"Unsupported cache backend: {cache_backend}")
yield
Loading