Commit 0d37ec80 by Calen Pennington

Change the central cache to store at two levels: first by scope, then by cache key

parent 645d2a72
...@@ -84,7 +84,7 @@ class UserStateCache(object): ...@@ -84,7 +84,7 @@ class UserStateCache(object):
self.course_id = course_id self.course_id = course_id
def cache_key_for_field_object(self, field_object): 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): class UserStateSummaryCache(object):
...@@ -102,7 +102,7 @@ class UserStateSummaryCache(object): ...@@ -102,7 +102,7 @@ class UserStateSummaryCache(object):
self.course_id = course_id self.course_id = course_id
def cache_key_for_field_object(self, field_object): 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): class PreferencesCache(object):
...@@ -120,7 +120,7 @@ class PreferencesCache(object): ...@@ -120,7 +120,7 @@ class PreferencesCache(object):
) )
def cache_key_for_field_object(self, field_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): class UserInfoCache(object):
...@@ -136,7 +136,7 @@ class UserInfoCache(object): ...@@ -136,7 +136,7 @@ class UserInfoCache(object):
) )
def cache_key_for_field_object(self, field_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): class FieldDataCache(object):
...@@ -158,7 +158,12 @@ class FieldDataCache(object): ...@@ -158,7 +158,12 @@ class FieldDataCache(object):
select_for_update: True if rows should be locked until end of transaction 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. 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 self.select_for_update = select_for_update
if asides is None: if asides is None:
...@@ -301,7 +306,7 @@ class FieldDataCache(object): ...@@ -301,7 +306,7 @@ class FieldDataCache(object):
return return
for field_object in cache._data: 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): def _fields_to_cache(self, descriptors):
""" """
...@@ -318,13 +323,13 @@ class FieldDataCache(object): ...@@ -318,13 +323,13 @@ class FieldDataCache(object):
Return the key used in the FieldDataCache for the specified KeyValueStore key Return the key used in the FieldDataCache for the specified KeyValueStore key
""" """
if key.scope == Scope.user_state: 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: 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: 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: elif key.scope == Scope.user_info:
return (key.scope, key.field_name) return key.field_name
def find(self, key): def find(self, key):
''' '''
...@@ -339,7 +344,7 @@ class FieldDataCache(object): ...@@ -339,7 +344,7 @@ class FieldDataCache(object):
# user we were constructed for. # user we were constructed for.
assert key.user_id == self.user.id 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): def find_or_create(self, key):
''' '''
...@@ -379,7 +384,7 @@ class FieldDataCache(object): ...@@ -379,7 +384,7 @@ class FieldDataCache(object):
) )
cache_key = self._cache_key_from_kvs_key(key) 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 return field_object
......
...@@ -230,7 +230,7 @@ class TestMissingStudentModule(TestCase): ...@@ -230,7 +230,7 @@ class TestMissingStudentModule(TestCase):
def test_set_field_in_missing_student_module(self): def test_set_field_in_missing_student_module(self):
"Test that setting a field in a missing StudentModule creates the student module" "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()) self.assertEquals(0, StudentModule.objects.all().count())
# We are updating a problem, so we write to courseware_studentmodulehistory # We are updating a problem, so we write to courseware_studentmodulehistory
...@@ -238,7 +238,7 @@ class TestMissingStudentModule(TestCase): ...@@ -238,7 +238,7 @@ class TestMissingStudentModule(TestCase):
with self.assertNumQueries(6): with self.assertNumQueries(6):
self.kvs.set(user_state_key('a_field'), 'a_value') 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()) self.assertEquals(1, StudentModule.objects.all().count())
student_module = StudentModule.objects.all()[0] student_module = StudentModule.objects.all()[0]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment