Version-aware Studio - version-checking modulestore

Description

Problem Summary:

Although the Split modulestore supports versions for structures and definitions, Studio does not know how to parse the versions and use them to detect when update conflicts have occurred. So the @strip_key decorator is used to strip the version information from the keys returned from the modulestore interface. Also, other modulestore operations outside of Studio, such as adding asset metadata to the modulestore, have lost production data due to not properly handling update conflicts.

To explain in detail, the pattern for updating structures is below:

  • version_structure() - reads a structure from MongoDB, deep-copies the existing structure, and updates its edit_info.

  • <edit structure> - could be adding/deleting blocks, adding/deleting metadata, changing structure, whatever...

  • update_structure() - saves the new structure to MongoDB

  • update_course_index() - updates the course index in the active_versions collection with the new structure ID

Suppose two operations are occurring at about the same time - operation A and B. And suppose the following scenario happens:

  1. Operation A: version_structure()

  2. Operation B: version_structure()

  3. Operation A: <edit structure>

  4. Operation B: <edit structure>

  5. Operation B: update_structure()

  6. Operation A: update_structure()

  7. Operation A: update_course_index()

  8. Operation B: update_course_index()

In this case, operation A's structure modifications would be lost in favor of operation B's modifications - since Operation B modified the course_index last. Operation A's structure would exist in the MongoDB collection but would have no structure descendants - it'd be a dead branch of the structure history, containing data that wouldn't be contained in the main structure branch.

To Fix:

Obviously Studio would need extensive changes to handle update conflicts, including:

  • making all course updates version-aware

  • UI for resolving when update collisions occur:

  • throwing away either set of changes?

  • merging both sets of changes?

Any modulestore calls that make updates would need to be modified to possibly throw a VersionConflictError. A structure update would read and check the current course index head in the last "Operation B:" step above against the course index head from which the structure was deep copied. If the course index head held a different value, then the code would know that another operation had modified the course index since the beginning of this operation. The modulestore code would then raise a VersionConflictError exception and an error would be reported back to the caller.

Steps to Reproduce

None

Current Behavior

None

Expected Behavior

None

Reason for Variance

None

Release Notes

None

User Impact Summary

None

Assignee

Unassigned

Reporter

Julia Eskew

Labels

Reach

None

Impact

None

Platform Area

None

Customer

None

Partner Manager

None

URL

None

Contributor Name

None

Groups with Read-Only Access

None

Actual Points

None

Category of Work

None

Platform Map Area (Levels 1 &amp; 2)

None

Platform Map Area (Levels 3 &amp; 4)

None

Priority

Unset

Epic Name

Version-aware Studio/modulestore
Configure