Open ormsbee opened 2 years ago
Explore relation to: https://github.com/openedx/platform-roadmap/issues/2
I created a scratch repo to test some of these ideas in (there is some hashing out of the data model for the core publishing app). A number of the structural ideas were adopted from a Django 2021 talk on Scaling Django to 500 Apps.
Some things that came up during the prototyping and discussion:
Doing the Publishing portion of this is mandatory, because everything else builds off of it. After that, doing partitioning and composition is probably the best bet, since it's relevant for v2 content libraries and the effort estimation API.
openedx_learning/apps/core
.learning_composition
instead of composition
.learning_publishing
will have a LearningContext
model that is general for all learning contexts (courses, libraries, etc.). An app can attach course-specific data to this by making their own Course
model that has a foreign key to LearningContext
.learning_composition/learning_composition_xblock
learning_composition
. For instance, we could do openedx_learning/apps/xblock/learning_composition_xblock
to group functionality specific to XBlocksdata.py
, api.py
, tasks.py
.models.py
files have only models, and never helper methods or other utilities.openedx_learning/apps/xblock/learning_composition_xblock
) can depend on the top level core apps.Possible areas of exploration on top of this smaller core:
Extract core learning concepts and data models into a new
openedx-learning
repository, with goal of creating a new, scalable core platform for learning innovation.Goals
Major Components
The high level components would include:
Composition
What permutation of a single unit does a user see? This would handle things like A/B tests, randomized problem selection, disabling content by enrollment type, adding staff-only debug markup, etc. There should be multiple backends for what can render a Unit, with the XBlock runtime being one of those.
Navigation
Sequence and Unit metadata, outlines, etc. How do you get to a particular piece of content you need to learn from? This would pull in parts of the Learning Sequences API from
edx-platform
.Partitioning
Low level utility that helps determine what users are in what groups for the purposes of A/B testing, enrollment tracks, etc. Used by both Composition and Navigation.
Policy
Content-related settings as they apply to the site as a whole, organizations, and individual courses. This covers a lot of what Course Overviews and course override waffle flags do today.
Publishing
Centralized list of Learning Contexts (e.g. Courses, Libraries), their published versions, and various content-related errors and warnings are associated with them. We need this to help us tackle the major issue we have today around publishing: it's an asynchronous process with many different components that sometimes take minutes to complete and may fail independently, leading to a mixed-published state. This is the most foundational component that others will be built on top of.
Scheduling
Lower level library for content scheduling information, likely pulling in most of what is
edx-when
today.Discovery/Design Phases
Full Implementation Phases
edx-when
.learning_sequences
API._Implementation Strategies
The following are some high level approaches/considerations with this new project.
Focus on content first.
Content data that lives in Studio is easy to re-build and backfill into new apps. User data is up to five orders of magnitude larger, and involves much larger challenges in terms of data migration.
Build Extensible Primitives
LearningContexts are a generic term that applies to Courses, Content Libraries, Learning Pathways, and any number of other collections of content that we want to discretely version and publish. We can centrally define logic around these, while leaving it up to higher layers to model specific types of LearningContexts in a pluggable way.
For instance, it makes sense for there to be a table of Courses, that have a foreign key to the LearningContexts table, which holds course-specific metadata. That table would have course-specific fields, and may even have a
null
learning context in the beginning (before any content is created).This kind of arrangement would lead to a three layered system:
openedx-learning
.openedx-learning
or outside. The most popular and useful ones could get folded into the repo over time.EnrollmentTrackOutlineProcessor
. These would be implemented outside theopenedx-learning
repo (many would live inedx-platform
).Implement Plugins in
edx-platform
We once attempted to lift the ModuleStores out of
edx-platform
and ran into a rat's nest of dependencies that made the task extremely difficult. My thought with things like this is to have plugin interfaces that go the other way from what we usually do–where the core framework logic is in apps in this new repo, and the little plugin objects are created in edx-platform (and optionally elsewhere as well).So to use a concrete example, say we migrate the
learning_sequences
app in edx-platform today to become part of the navigation app in this new repo. The navigation app will then have the concept of OutlineProcessors–an object interface for different concerns that have to modify the set of things you can see or access in a course outline. The navigation app would have the logic for running OutlineProcessors, reading those values from a list defined in Django settings. TheEnrollmentOutlineProcessor
would be defined in edx-platform (and likely have imports to a bunch of things also in edx-platform), and then be specified in the settings file.By doing this, we can keep some of the crazy logic and dependencies in edx-platform–it would allow us to move things more incrementally, without taking huge risks.
See Also
Original post: