Make path_to_location use bulk_write_operation for performance.
This commit is contained in:
committed by
Calen Pennington
parent
7d8088d26b
commit
e624ff3b04
@@ -651,5 +651,8 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
|
||||
If course_id is None, the default store is used.
|
||||
"""
|
||||
store = self._get_modulestore_for_courseid(course_id)
|
||||
with store.bulk_write_operations(course_id):
|
||||
if hasattr(store, 'bulk_write_operations'):
|
||||
with store.bulk_write_operations(course_id):
|
||||
yield
|
||||
else:
|
||||
yield
|
||||
|
||||
@@ -68,39 +68,41 @@ def path_to_location(modulestore, usage_key):
|
||||
newpath = (next_usage, path)
|
||||
queue.append((parent, newpath))
|
||||
|
||||
if not modulestore.has_item(usage_key):
|
||||
raise ItemNotFoundError(usage_key)
|
||||
# doesn't write but does multiple reads. bulk_write minimizes reads too
|
||||
with modulestore.bulk_write_operations(usage_key.course_key):
|
||||
if not modulestore.has_item(usage_key):
|
||||
raise ItemNotFoundError(usage_key)
|
||||
|
||||
path = find_path_to_course()
|
||||
if path is None:
|
||||
raise NoPathToItem(usage_key)
|
||||
path = find_path_to_course()
|
||||
if path is None:
|
||||
raise NoPathToItem(usage_key)
|
||||
|
||||
n = len(path)
|
||||
course_id = path[0].course_key
|
||||
# pull out the location names
|
||||
chapter = path[1].name if n > 1 else None
|
||||
section = path[2].name if n > 2 else None
|
||||
# Figure out the position
|
||||
position = None
|
||||
n = len(path)
|
||||
course_id = path[0].course_key
|
||||
# pull out the location names
|
||||
chapter = path[1].name if n > 1 else None
|
||||
section = path[2].name if n > 2 else None
|
||||
# Figure out the position
|
||||
position = None
|
||||
|
||||
# This block of code will find the position of a module within a nested tree
|
||||
# of modules. If a problem is on tab 2 of a sequence that's on tab 3 of a
|
||||
# sequence, the resulting position is 3_2. However, no positional modules
|
||||
# (e.g. sequential and videosequence) currently deal with this form of
|
||||
# representing nested positions. This needs to happen before jumping to a
|
||||
# module nested in more than one positional module will work.
|
||||
if n > 3:
|
||||
position_list = []
|
||||
for path_index in range(2, n - 1):
|
||||
category = path[path_index].block_type
|
||||
if category == 'sequential' or category == 'videosequence':
|
||||
section_desc = modulestore.get_item(path[path_index])
|
||||
# this calls get_children rather than just children b/c old mongo includes private children
|
||||
# in children but not in get_children
|
||||
child_locs = [c.location for c in section_desc.get_children()]
|
||||
# positions are 1-indexed, and should be strings to be consistent with
|
||||
# url parsing.
|
||||
position_list.append(str(child_locs.index(path[path_index + 1]) + 1))
|
||||
position = "_".join(position_list)
|
||||
# This block of code will find the position of a module within a nested tree
|
||||
# of modules. If a problem is on tab 2 of a sequence that's on tab 3 of a
|
||||
# sequence, the resulting position is 3_2. However, no positional modules
|
||||
# (e.g. sequential and videosequence) currently deal with this form of
|
||||
# representing nested positions. This needs to happen before jumping to a
|
||||
# module nested in more than one positional module will work.
|
||||
if n > 3:
|
||||
position_list = []
|
||||
for path_index in range(2, n - 1):
|
||||
category = path[path_index].block_type
|
||||
if category == 'sequential' or category == 'videosequence':
|
||||
section_desc = modulestore.get_item(path[path_index])
|
||||
# this calls get_children rather than just children b/c old mongo includes private children
|
||||
# in children but not in get_children
|
||||
child_locs = [c.location for c in section_desc.get_children()]
|
||||
# positions are 1-indexed, and should be strings to be consistent with
|
||||
# url parsing.
|
||||
position_list.append(str(child_locs.index(path[path_index + 1]) + 1))
|
||||
position = "_".join(position_list)
|
||||
|
||||
return (course_id, chapter, section, position)
|
||||
return (course_id, chapter, section, position)
|
||||
|
||||
@@ -717,7 +717,7 @@ class TestMixedModuleStore(unittest.TestCase):
|
||||
# TODO: LMS-11220: Document why draft send count is 5
|
||||
# TODO: LMS-11220: Document why draft find count is 18
|
||||
# TODO: LMS-11220: Document why split find count is 16
|
||||
@ddt.data(('draft', [18, 5], 0), ('split', [16, 6], 0))
|
||||
@ddt.data(('draft', [19, 5], 0), ('split', [2, 2], 0))
|
||||
@ddt.unpack
|
||||
def test_path_to_location(self, default_ms, num_finds, num_sends):
|
||||
"""
|
||||
@@ -736,7 +736,6 @@ class TestMixedModuleStore(unittest.TestCase):
|
||||
(course_key, "Chapter_x", None, None)),
|
||||
)
|
||||
|
||||
mongo_store = self.store._get_modulestore_for_courseid(self._course_key_from_string(self.MONGO_COURSEID))
|
||||
for location, expected in should_work:
|
||||
with check_mongo_calls(num_finds.pop(0), num_sends):
|
||||
self.assertEqual(path_to_location(self.store, location), expected)
|
||||
|
||||
Reference in New Issue
Block a user