Skip to content
This repository has been archived by the owner on Jan 28, 2020. It is now read-only.

Commit

Permalink
Merge pull request #533 from mitodl/bug/skm/529_vocab_cache
Browse files Browse the repository at this point in the history
Fixed caching bug.
  • Loading branch information
ShawnMilo committed Aug 18, 2015
2 parents 2299696 + 2fc2e01 commit 200d92a
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
3 changes: 2 additions & 1 deletion search/search_indexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ def get_vocabs(course_id, resource_id, solo_update=False):
# terms for that LearningResource. Otherwise, looking up the vocabularies
# for that resource will refill the cache for the entire course. If there
# is already a value, retain it.
resource_ids = LearningResource.objects.all().values_list('id', flat=True)
resource_ids = LearningResource.objects.filter(
course__id=course_id).values_list('id', flat=True)
for resource_id in resource_ids:
rkey = "vocab_cache_{0}".format(resource_id)
cache.set(rkey, cache.get(rkey, {}))
Expand Down
52 changes: 52 additions & 0 deletions search/tests/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@
log = logging.getLogger(__name__)


def copy_instance(instance):
"""
Make a copy of a model instance. The copy will need to be saved by the
caller because this function doesn't know what fields must be unique.
Args:
instance (models.Model): models.Model instance
Returns:
original (models.Model): models.Model instance
clone (models.Model): models.Model instance
"""
original_id = instance.pk
clone = instance
clone.pk = None
return instance.__class__.objects.get(id=original_id), clone


def set_cache_timeout(seconds):
"""Override the cache timeout for testing."""
cache.default_timeout = seconds
Expand Down Expand Up @@ -245,3 +262,38 @@ def test_term_cache_without_data(self):
a LearningResource isn't tagged with any terms.
"""
self.thrice()

def test_vocab_cache_by_course(self):
"""
Ensure that get_vocabs for one course doesn't
pollute the cache for another course.
"""
# Create a resource in a separate course.
self.course, course2 = copy_instance(self.course)
self.resource, resource2 = copy_instance(self.resource)
course2.run = "{0} part 2".format(self.course.run)
course2.save()
resource2.course = course2
resource2.save()

key1 = "vocab_cache_{0}".format(self.resource.id)
key2 = "vocab_cache_{0}".format(resource2.id)

# Resources were recently saved, so the keys should be in the cache.
self.assertIn(key1, cache)
self.assertIn(key2, cache)

# Getting vocabs for a resource should not refresh the cache for
# resources in another course.
cache.clear()
self.resource.save()
self.assertIn(key1, cache)
self.assertNotIn(key2, cache)

# Resource for the same course are updated.
resource2.course = self.resource.course
resource2.save()
cache.clear()
self.resource.save()
self.assertIn(key1, cache)
self.assertIn(key2, cache)

0 comments on commit 200d92a

Please sign in to comment.