Skip to content

Commit

Permalink
Merge pull request #38 from edx/alangsto/add_content_cache
Browse files Browse the repository at this point in the history
feat: cache unit content
  • Loading branch information
alangsto authored Dec 5, 2023
2 parents 7213dba + 0000980 commit 4537003
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Change Log

.. There should always be an "Unreleased" section for changes pending release.
Unreleased
**********
* Add content cache

1.5.0 - 2023-10-18
******************
* Add management command to generate course prompts
Expand Down
24 changes: 19 additions & 5 deletions learning_assistant/api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
"""
Library for the learning_assistant app.
"""
from django.conf import settings
from django.core.cache import cache
from edx_django_utils.cache import get_cache_key

from learning_assistant.constants import ACCEPTED_CATEGORY_TYPES, CATEGORY_TYPE_MAP
from learning_assistant.models import CoursePrompt
from learning_assistant.platform_imports import (
Expand Down Expand Up @@ -93,8 +97,18 @@ def get_block_content(request, user_id, course_id, unit_usage_key):
length - the cummulative length of a block's children's content
items - a list of dictionaries containing the content type and text for each child
"""
block = get_single_block(request, user_id, course_id, unit_usage_key)

length, items = _get_children_contents(block)

return length, items
cache_key = get_cache_key(
resource='learning_assistant',
user_id=user_id,
course_id=course_id,
unit_usage_key=unit_usage_key
)
cache_data = cache.get(cache_key)

if not isinstance(cache_data, dict):
block = get_single_block(request, user_id, course_id, unit_usage_key)
length, items = _get_children_contents(block)
cache_data = {'content_length': length, 'content_items': items}
cache.set(cache_key, cache_data, getattr(settings, 'LEARNING_ASSISTANT_CACHE_TIMEOUT', 360))

return cache_data['content_length'], cache_data['content_items']
2 changes: 1 addition & 1 deletion learning_assistant/text_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def __init__(self):

def handle_starttag(self, tag, _):
"""On each tag, check whether this is a tag we think is content."""
tags_to_filter = getattr(settings, 'HTML_TAGS_TO_REMOVE', None)
tags_to_filter = getattr(settings, 'LEARNING_ASSISTANT_HTML_TAGS_TO_REMOVE', None)
self._is_content = not (tags_to_filter and tag in tags_to_filter)

def handle_data(self, data):
Expand Down
6 changes: 6 additions & 0 deletions test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,9 @@ def root(*args):
DISCOVERY_BACKEND_SERVICE_EDX_OAUTH2_PROVIDER_URL = 'http://edx.devstack.lms:18000/oauth2'
DISCOVERY_BACKEND_SERVICE_EDX_OAUTH2_KEY = 'discovery-backend-service-key'
DISCOVERY_BACKEND_SERVICE_EDX_OAUTH2_SECRET = 'discovery-backend-service-secret'

CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
}
}
13 changes: 13 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from unittest.mock import MagicMock, patch

import ddt
from django.core.cache import cache
from django.test import TestCase
from opaque_keys.edx.keys import UsageKey

Expand Down Expand Up @@ -91,6 +92,8 @@ class GetBlockContentAPITests(TestCase):
"""

def setUp(self):
cache.clear()

self.children = [
FakeChild('html', '01', '''
<p>
Expand Down Expand Up @@ -187,7 +190,17 @@ def test_get_block_content(self, mock_get_children_contents, mock_get_single_blo

length, items = get_block_content(request, user_id, course_id, unit_usage_key)

mock_get_children_contents.assert_called_once()
mock_get_children_contents.assert_called_with(self.block)

self.assertEqual(length, len(block_content))
self.assertEqual(items, content_items)

# call get_block_content again with same args to assert that cache is used
length, items = get_block_content(request, user_id, course_id, unit_usage_key)

# assert that the mock for _get_children_contents has not been called again,
# as subsequent calls should hit the cache
mock_get_children_contents.assert_called_once()
self.assertEqual(length, len(block_content))
self.assertEqual(items, content_items)

0 comments on commit 4537003

Please sign in to comment.