Xqueue callback acquires lock on StudentModule to avoid race condition

This commit is contained in:
kimth
2012-08-14 18:13:53 -04:00
parent 49d3674601
commit 75eee443ff
2 changed files with 15 additions and 11 deletions

View File

@@ -67,7 +67,7 @@ class StudentModuleCache(object):
"""
A cache of StudentModules for a specific student
"""
def __init__(self, user, descriptors):
def __init__(self, user, descriptors, acquire_lock=False):
'''
Find any StudentModule objects that are needed by any descriptor
in descriptors. Avoids making multiple queries to the database.
@@ -86,17 +86,23 @@ class StudentModuleCache(object):
self.cache = []
chunk_size = 500
for id_chunk in [module_ids[i:i + chunk_size] for i in xrange(0, len(module_ids), chunk_size)]:
self.cache.extend(StudentModule.objects.filter(
student=user,
module_state_key__in=id_chunk)
)
if acquire_lock:
self.cache.extend(StudentModule.objects.select_for_update().filter(
student=user,
module_state_key__in=id_chunk)
)
else:
self.cache.extend(StudentModule.objects.filter(
student=user,
module_state_key__in=id_chunk)
)
else:
self.cache = []
@classmethod
def cache_for_descriptor_descendents(cls, user, descriptor, depth=None, descriptor_filter=lambda descriptor: True):
def cache_for_descriptor_descendents(cls, user, descriptor, depth=None, descriptor_filter=lambda descriptor: True, acquire_lock=False):
"""
descriptor: An XModuleDescriptor
depth is the number of levels of descendent modules to load StudentModules for, in addition to
@@ -122,7 +128,7 @@ class StudentModuleCache(object):
descriptors = get_child_descriptors(descriptor, depth, descriptor_filter)
return StudentModuleCache(user, descriptors)
return StudentModuleCache(user, descriptors, acquire_lock)
def _get_module_state_keys(self, descriptors):
'''