From 0d37ec8099ba28ba76d34a754c91fb2944898b87 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Wed, 8 Apr 2015 16:48:43 -0400 Subject: [PATCH] Change the central cache to store at two levels: first by scope, then by cache key --- lms/djangoapps/courseware/model_data.py | 29 +++++++++++-------- .../courseware/tests/test_model_data.py | 4 +-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/lms/djangoapps/courseware/model_data.py b/lms/djangoapps/courseware/model_data.py index b48e9b8ad1..6bfa2b65dc 100644 --- a/lms/djangoapps/courseware/model_data.py +++ b/lms/djangoapps/courseware/model_data.py @@ -84,7 +84,7 @@ class UserStateCache(object): self.course_id = course_id def cache_key_for_field_object(self, field_object): - return (Scope.user_state, field_object.module_state_key.map_into_course(self.course_id)) + return field_object.module_state_key.map_into_course(self.course_id) class UserStateSummaryCache(object): @@ -102,7 +102,7 @@ class UserStateSummaryCache(object): self.course_id = course_id def cache_key_for_field_object(self, field_object): - return (Scope.user_state_summary, field_object.usage_id.map_into_course(self.course_id), field_object.field_name) + return (field_object.usage_id.map_into_course(self.course_id), field_object.field_name) class PreferencesCache(object): @@ -120,7 +120,7 @@ class PreferencesCache(object): ) def cache_key_for_field_object(self, field_object): - return (Scope.preferences, field_object.module_type, field_object.field_name) + return (field_object.module_type, field_object.field_name) class UserInfoCache(object): @@ -136,7 +136,7 @@ class UserInfoCache(object): ) def cache_key_for_field_object(self, field_object): - return (Scope.user_info, field_object.field_name) + return field_object.field_name class FieldDataCache(object): @@ -158,7 +158,12 @@ class FieldDataCache(object): select_for_update: True if rows should be locked until end of transaction asides: The list of aside types to load, or None to prefetch no asides. ''' - self.cache = {} + self.cache = { + Scope.user_state: {}, + Scope.user_info: {}, + Scope.preferences: {}, + Scope.user_state_summary: {}, + } self.select_for_update = select_for_update if asides is None: @@ -301,7 +306,7 @@ class FieldDataCache(object): return for field_object in cache._data: - self.cache[cache.cache_key_for_field_object(field_object)] = field_object + self.cache[scope][cache.cache_key_for_field_object(field_object)] = field_object def _fields_to_cache(self, descriptors): """ @@ -318,13 +323,13 @@ class FieldDataCache(object): Return the key used in the FieldDataCache for the specified KeyValueStore key """ if key.scope == Scope.user_state: - return (key.scope, key.block_scope_id) + return key.block_scope_id elif key.scope == Scope.user_state_summary: - return (key.scope, key.block_scope_id, key.field_name) + return (key.block_scope_id, key.field_name) elif key.scope == Scope.preferences: - return (key.scope, BlockTypeKeyV1(key.block_family, key.block_scope_id), key.field_name) + return (BlockTypeKeyV1(key.block_family, key.block_scope_id), key.field_name) elif key.scope == Scope.user_info: - return (key.scope, key.field_name) + return key.field_name def find(self, key): ''' @@ -339,7 +344,7 @@ class FieldDataCache(object): # user we were constructed for. assert key.user_id == self.user.id - return self.cache.get(self._cache_key_from_kvs_key(key)) + return self.cache[key.scope].get(self._cache_key_from_kvs_key(key)) def find_or_create(self, key): ''' @@ -379,7 +384,7 @@ class FieldDataCache(object): ) cache_key = self._cache_key_from_kvs_key(key) - self.cache[cache_key] = field_object + self.cache[key.scope][cache_key] = field_object return field_object diff --git a/lms/djangoapps/courseware/tests/test_model_data.py b/lms/djangoapps/courseware/tests/test_model_data.py index ca62da4e80..3355970562 100644 --- a/lms/djangoapps/courseware/tests/test_model_data.py +++ b/lms/djangoapps/courseware/tests/test_model_data.py @@ -230,7 +230,7 @@ class TestMissingStudentModule(TestCase): def test_set_field_in_missing_student_module(self): "Test that setting a field in a missing StudentModule creates the student module" - self.assertEquals(0, len(self.field_data_cache.cache)) + self.assertEquals(0, sum(len(cache) for cache in self.field_data_cache.cache.values())) self.assertEquals(0, StudentModule.objects.all().count()) # We are updating a problem, so we write to courseware_studentmodulehistory @@ -238,7 +238,7 @@ class TestMissingStudentModule(TestCase): with self.assertNumQueries(6): self.kvs.set(user_state_key('a_field'), 'a_value') - self.assertEquals(1, len(self.field_data_cache.cache)) + self.assertEquals(1, sum(len(cache) for cache in self.field_data_cache.cache.values())) self.assertEquals(1, StudentModule.objects.all().count()) student_module = StudentModule.objects.all()[0]