Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: keep learner state associated after libraries migration #33920

Conversation

connorhaugh
Copy link
Contributor

@connorhaugh connorhaugh commented Dec 13, 2023

Description

Upgrading an LCB's source lib from V1 to V2 disassociates learner state, because it seems child use keys are derived differently between V1 and V2.

Supporting information

https://twou.slack.com/archives/C05NT2YN820/p1702047279641349

Testing instructions

  1. Create an LCB
  2. Create a v1 library
  3. Associate the V1 library with the LCB. set max_count to 1.
  4. View the LCB in LMS (generating learner state for you). note the LC block's children for later comparison using "debug info".
  5. Migrate the v1 library to v2 using ./manage.py cms copy_libraries_from_v1_to_v2 '11111111-2111-4111-8111-111111111111' ./list_of--library-locators.csv <v1 lib id>
  6. Switch the LCB to be pointing at the created v2 lib by changing the source lib attribute.
  7. View the LCB in LMS, you should see the same 1 block from before and the children should be identical, but the source_library_id is a v2 lib

Copy link
Member

@kdmccormick kdmccormick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still need to test it out, but here's some feedback in the meantime.

openedx/core/djangoapps/content_libraries/api.py Outdated Show resolved Hide resolved
openedx/core/djangoapps/content_libraries/api.py Outdated Show resolved Hide resolved
openedx/core/djangoapps/content_libraries/api.py Outdated Show resolved Hide resolved
@kdmccormick
Copy link
Member

I tested with Tutor Dev, and confirmed that the keys didn't match up before, but they do now 🔥 Nice work. If you address my comments I'm good to give this a ✅

FWIW, I had to enable CELERY_ALWAYS_EAGER in order to get the migration mgmt command to work for me, but that's an issue for another day.

@connorhaugh connorhaugh force-pushed the feat--keep-learner-state-associated-after-libraries-migration branch 2 times, most recently from 3c18ece to 472806d Compare December 14, 2023 18:17
@kdmccormick kdmccormick added the create-sandbox open-craft-grove should create a sandbox environment from this PR label Dec 15, 2023
Copy link
Member

@kdmccormick kdmccormick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@kdmccormick kdmccormick removed the create-sandbox open-craft-grove should create a sandbox environment from this PR label Dec 15, 2023
Copy link
Member

@kdmccormick kdmccormick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, one more minor suggestion. Feel free to merge if you apply this.

openedx/core/djangoapps/content_libraries/tasks.py Outdated Show resolved Hide resolved
@connorhaugh connorhaugh merged commit 2eac2ef into master Dec 18, 2023
64 checks passed
@connorhaugh connorhaugh deleted the feat--keep-learner-state-associated-after-libraries-migration branch December 18, 2023 20:14
@edx-pipeline-bot
Copy link
Contributor

2U Release Notice: This PR has been deployed to the edX staging environment in preparation for a release to production.

@edx-pipeline-bot
Copy link
Contributor

2U Release Notice: This PR has been deployed to the edX production environment.

kdmccormick added a commit to kdmccormick/edx-platform that referenced this pull request Jan 16, 2024
After we merged this PR: openedx#33920
this error began popping up in logs:

    Unable to load XBlock 'staffgradedxblock'
    ....
    ImportError: cannot import name 'get_course_blocks' from
    partially initialized module 'lms.djangoapps.course_blocks.api'
    (most likely due to a circular import) ...

The root cause was the new imports of `derived_key` and `BlockKey` into
xmodule/library_content_block.py. Those new imports come from
xmodule/modulestore/store_utilities.py, which runs
`XBlock.load_classes()` at the module level, which fails because we are
still in the process of loading xmodule/library_content_block.

As a solution, we move both `derived_key` and `BlockKey` to
xmodule/util/keys.py. We could potentially move that file to opaque-keys
eventually, depending on how well we think that those concepts generalize.

Also:

* We rename the function from derived_key to derive_key, as
  functions should be verbs.
* We combine the first to parameters of derive_key (a source ContextKey
  and a source BlockKey) into a single parameter (a source UsageKey). In
  my opinion, this makes the function call easier to understand.
kdmccormick added a commit that referenced this pull request Jan 16, 2024
After we merged this PR: #33920
this error began popping up in logs:

    Unable to load XBlock 'staffgradedxblock'
    ....
    ImportError: cannot import name 'get_course_blocks' from
    partially initialized module 'lms.djangoapps.course_blocks.api'
    (most likely due to a circular import) ...

The root cause was the new imports of `derived_key` and `BlockKey` into
xmodule/library_content_block.py. Those new imports come from
xmodule/modulestore/store_utilities.py, which runs
`XBlock.load_classes()` at the module level, which fails because we are
still in the process of loading xmodule/library_content_block.

As a solution, we move both `derived_key` and `BlockKey` to
xmodule/util/keys.py. We could potentially move that file to opaque-keys
eventually, depending on how well we think that those concepts generalize.

Also:

* We rename the function from derived_key to derive_key, as
  functions should be verbs.
* We combine the first to parameters of derive_key (a source ContextKey
  and a source BlockKey) into a single parameter (a source UsageKey). In
  my opinion, this makes the function call easier to understand.
mariajgrimaldi pushed a commit to eduNEXT/edunext-platform that referenced this pull request Jan 23, 2024
After we merged this PR: openedx/edx-platform#33920
this error began popping up in logs:

    Unable to load XBlock 'staffgradedxblock'
    ....
    ImportError: cannot import name 'get_course_blocks' from
    partially initialized module 'lms.djangoapps.course_blocks.api'
    (most likely due to a circular import) ...

The root cause was the new imports of `derived_key` and `BlockKey` into
xmodule/library_content_block.py. Those new imports come from
xmodule/modulestore/store_utilities.py, which runs
`XBlock.load_classes()` at the module level, which fails because we are
still in the process of loading xmodule/library_content_block.

As a solution, we move both `derived_key` and `BlockKey` to
xmodule/util/keys.py. We could potentially move that file to opaque-keys
eventually, depending on how well we think that those concepts generalize.

Also:

* We rename the function from derived_key to derive_key, as
  functions should be verbs.
* We combine the first to parameters of derive_key (a source ContextKey
  and a source BlockKey) into a single parameter (a source UsageKey). In
  my opinion, this makes the function call easier to understand.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants