feat: Enhance UserStateCache and FieldDataCache with dynamic child handling - #416
Open
mraman-2U wants to merge 1 commit into
Open
feat: Enhance UserStateCache and FieldDataCache with dynamic child handling#416mraman-2U wants to merge 1 commit into
mraman-2U wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR lays groundwork to improve performance and authoring guardrails for large Library Content / Item Bank assessments by (a) reducing unnecessary user-state prefetch work, and (b) introducing an opt-in “shell + batch children” rendering path for incremental loading, plus Studio validation for large max_count.
Changes:
- Add dynamic-child-aware traversal in
FieldDataCacheand optimizeget_manyvia query shaping + lazy JSON parsing to reduce DB/CPU overhead. - Add Phase B1 shell rendering (
render_mode=shell) and a new authenticated batch child-render API (/api/courseware/v1/xblock_children/) with a lazy placeholder template. - Add Phase C Studio guardrails for large
max_countwith a configurable threshold and an optional hard-cap waffle flag, plus tests and implementation-plan docs.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| xmodule/tests/test_library_content.py | Adds Studio validation test coverage for large max_count warning/error behavior. |
| xmodule/tests/test_item_bank.py | Adds parallel Studio validation test coverage for Item Bank large max_count. |
| xmodule/library_content_block.py | Hooks large-max_count guardrail into legacy library content validation. |
| xmodule/item_bank_block.py | Adds shell student view, large-max_count validation helpers, and updated help text. |
| scripts/field_data_cache_integration/validate_dynamic_children_prefetch.py | Adds a devstack integration validator script for dynamic-children prefetch behavior/metrics. |
| scripts/field_data_cache_integration/B1_shell_batch_curl.rst | Adds curl/Postman examples for shell render + batch children API. |
| openedx/core/djangoapps/courseware_api/views.py | Adds DRF view for the batch child-render endpoint. |
| openedx/core/djangoapps/courseware_api/urls.py | Routes the new /api/courseware/v1/xblock_children/ endpoint. |
| openedx/core/djangoapps/courseware_api/tests/test_views.py | Adds basic request-validation tests for the new API. |
| lms/templates/vert_module_lazy.html | Introduces a lazy-placeholder vertical template + postMessage hooks for batching. |
| lms/envs/common.py | Adds LMS settings for lazy render thresholds, batch max, and Studio guardrail defaults. |
| lms/djangoapps/courseware/views/views.py | Adds render_mode handling and integrates shell-mode decision + cache-depth control. |
| lms/djangoapps/courseware/user_state_client.py | Optimizes get_many DB shape and adds lazy JSON parsing for user state. |
| lms/djangoapps/courseware/toggles.py | Adds a waffle flag for enabling lazy shell rendering in courseware. |
| lms/djangoapps/courseware/tests/test_user_state_client.py | Adds unit/integration tests for query shaping + lazy state parsing behavior. |
| lms/djangoapps/courseware/tests/test_model_data.py | Adds tests for dynamic-children traversal and lazy state behavior in caches. |
| lms/djangoapps/courseware/tests/test_lazy_xblock_render.py | Adds unit tests for shell-mode eligibility helpers. |
| lms/djangoapps/courseware/model_data.py | Implements _children_for_field_data_cache and lazy overlay behavior in UserStateCache. |
| lms/djangoapps/courseware/block_render.py | Adds shell-mode helpers and render_xblock_children batch rendering implementation. |
| docs/implementation_plans/phase-c-studio-warning-sample.rst | Documents sample Studio warning/error messaging for Phase C. |
| docs/implementation_plans/assessments-not-loading-performance.md | Adds the broader phased implementation plan and acceptance criteria. |
| cms/envs/common.py | Adds CMS-side defaults for the Studio guardrail settings. |
| cms/djangoapps/contentstore/toggles.py | Adds the Studio hard-cap waffle flag and helper. |
Suppressed comments (2)
scripts/field_data_cache_integration/validate_dynamic_children_prefetch.py:290
- Same iterator-consumption issue as above: after
keys = list(block_keys), the patched method should passkeysintooriginal_get_manyto be robust to iterator inputs.
yield from original_get_many(self, username, block_keys, scope=scope, fields=fields)
scripts/field_data_cache_integration/B1_shell_batch_curl.rst:68
- The closing triple-quote at the end of this .rst file should be removed (it looks like an accidental carryover from a Python docstring).
"""
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+1657
to
+1662
| # Decide shell vs full before binding so FieldDataCache depth can stay shallow. | ||
| unbound_block = store.get_item(usage_key) | ||
| use_shell = should_use_shell_render(course_key, requested_render_mode, unbound_block) | ||
| set_custom_attribute('render_mode', 'shell' if use_shell else 'full') | ||
| cache_depth = field_data_cache_depth_for_shell(unbound_block) if use_shell else None | ||
|
|
| metrics.block_types_requested[block_type] = ( | ||
| metrics.block_types_requested.get(block_type, 0) + 1 | ||
| ) | ||
| yield from original_get_many(self, username, block_keys, scope=scope, fields=fields) |
Comment on lines
+1
to
+2
| """ | ||
| curl / Postman examples for Phase B1 shell + batch child API. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces several features and configuration options to improve the performance and authoring experience for large library content (item banks) in Studio and the LMS, focusing on validation, performance guardrails, and implementation planning. The most important changes are:
Studio Validation and Guardrails
LIBRARY_CONTENT_MAX_COUNT_WARNING_THRESHOLD(default 25) to control when Studio warns authors about largemax_count(item bank Count) values that may cause slow loads for learners.contentstore.hard_cap_library_content_max_count) to optionally escalate the Studio warning to an error for organizations that want a hard cap, with a helper function for checking the flag.max_countexceeds the threshold, and how an optional runbook URL can be appended.Implementation Plan Documentation
docs/implementation_plans/assessments-not-loading-performance.md) detailing phased backend and frontend improvements to address large assessment render performance, including dynamic child traversal, SQL and JSON optimizations, shell rendering, MFE lazy loading, and Studio guardrails. [1] [2]Codebase Preparation
get_block_by_usage_idto accept an optionalfield_data_cache_depthargument, supporting shell-mode rendering and batch child API for incremental loading in the LMS. [1] [2] [3]These changes collectively lay the groundwork for both immediate validation improvements in Studio and future backend/frontend optimizations to support scalable, performant delivery of large item bank assessments.…ndling
Description
Describe what this pull request changes, and why. Include implications for people using this change.
Design decisions and their rationales should be documented in the repo (docstring / ADR), per
OEP-19, and can be
linked here.
Useful information to include:
"Developer", and "Operator".
changes.
Supporting information
Link to other information about the change, such as Jira issues, GitHub issues, or Discourse discussions.
Be sure to check they are publicly readable, or if not, repeat the information here.
Testing instructions
Please provide detailed step-by-step instructions for testing this change.
Deadline
"None" if there's no rush, or provide a specific date or event (and reason) if there is one.
Other information
Include anything else that will help reviewers and consumers understand the change.