Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This diagram shows the two transforms that are applied to content, to bring it from the write-optimized Blockstore to the dynamic learning experience:

Design Details

Here are some of the features of this system design in more detail:

Courses are authored in two phases

All courses are initially authored as a "course template"; this would be similar to how courses are authored in Studio today, except that a course template cannot be directly used by learners, and the course content would be saved into Blockstore instead of the modulestore. Before a course can be used by learners, at least one "course run" must be created from the template.

A course template includes:

  • Name of the course
  • The full course outline (list of chapters, subsections, and units in the course)
  • All the course content (units consisting of XBlocks, plus any files/images/textbooks etc.)
  • Course authoring team ( + author bios, if those should appear on the course about page)
  • Default relative due dates (no absolute dates, but things like "By default, the section 'Week 2' is due two weeks after course start date")
  • Content groups
  • License (either a creative commons license or "All Rights Reserved")
  • "Field Rules" that affect XBlock behavior
    • This is a list of rules that override the default or value of any XBlock Scope.settings/Scope.content fields, e.g. "set max_attempts default to 3 for all 'problem' XBlocks in this course"

A course run consists of the following data, which is not included in the course template:

  • Name of the course run
  • Start date, end date, due dates
  • Cohort definitions/settings
  • Grading policy (the course template can include a default policy, which the run may or may not override)
  • Instructors and TAs ( + Instructor bios and TA bios, if those should appear on the course about page)
  • Enrollment restrictions
  • Customizations to the course outline and content ( add/remove chapters, subsections, and units )
  • "Field Rule Overrides" that affect XBlock Behavior
    • e.g. "set max_attempts default to  for all 'problem' XBlocks in Introduction chapter"

Most courses will have one template with one run, but many use cases (that use the CCX feature today) will see multiple runs per course template.

Rationale: Splitting course authoring into two phases allows a more clear separation between the "course author" role and the "course instructor" role; for example, today there is no way to grant a user permission to edit a course in Studio without also giving them access to view data about all students who are enrolled in the course. This design also removes the need to treat "CCX" courses as a special case (essentially, this design treats all courses in a similar way to today's "CCX" courses, which improves the architecture of the system by treating all courses consistently and removing a number of special cases that currently exist to support CCX).

Outline is a first-class concept

In the current Open edX platform, a course consists of a directed acyclic graph of XBlocks, with a root "course" node, which has several "chapter" children, and so on. The "course outline" is defined by the XBlock graph. 

In this new design, the course outline is no longer an XBlock graph at all; rather it is a simple rooted tree data structure that optionally defines the sections, subsections, and units in the course, along with their metadata such as permissions, visibility and due dates. The outline is stored in a JSON file in the course's Blockstore Bundle.

Rationale: Separating the outline from any XBlock runtime allows for much more efficient understanding and querying of the course outline, and provides better separation of concerns. Applying transformations to the outline (add/remove sections for certain users/runs only, shuffle them around adaptively, etc.) becomes much easier. The system can also support new types of micro learning experiences where, for example, the "course outline" consists of a single unit that is meant to be embedded into a blog post or another course. Finally, this design will explicitly disallow units that have multiple parents, which causes some issues in the current LMS.

Transforms Apply -izations

Building on the success of the "block transformers" in the current LMS, all learnable content will go through two distinct "transforms" which will each apply customizations and optimizations to the learnable content.

Courses, content, etc. will be stored in the Blockstore in a write-optimized form - course outlines will be JSON files, XBlock content will be stored as OLX (XML), and other data (instructor bios, lists of XBlock field overrides, etc.) will be stored in JSON format. Transform 1 will ingest the write-optimized content from a course template, then merge it with any applicable run-specific data (e.g. start date, content customizations), and produce a read-optimized course bundle (the "compiled course"). The compiled course may be in some format other than JSON/XML/etc. (e.g. python data structures, or protobuf ?), and will consist of the course outline and the course content will all applicable overrides (from the course template + course run settings) applied to each.

The LMS will only ever read the compiled course, and will never read the data that precedes transform 1.

While the compiled course which is output from Transform 1 can be cached until a change to the course is published, Transform 2 will be a more real-time transformation which applies user-specific changes to the compiled course. This may include checking user permissions and modifying the course accordingly, applying individual due dates, loading and assigning randomized content from a compiled content library, showing/hiding content based on content groups / cohorts, and even modifying content visibility based on the recommendations of an adaptive learning engine. The output of Transform 2 will be in the same format as the output of Transform 1.