Total Knowledge Projects Jobs Clientele Contact

UU Tech

Personal tools
From Total Knowledge
Revision as of 21:00, 23 May 2011 by Iluxa (Talk | contribs)
(diff) ←Older revision | Current revision (diff) | Newer revision→ (diff)
Jump to: navigation, search

Technological aspects of UU implementation.



Like in Wiki, there are two kinds of edits:

1. Versioned edits
2. Minor edits

Minor edits do not create new versions of the document, but change existing version instead. As such, they are irreversible. Only latest version can be edited.

It is author's decision, wether to designate change as minor or as versioned.

When a new version is created, all objects linking to this one are notified. Their action can be one of the following:

  • Silently use new version
  • Use new version and notify owner
  • Notify owner and keep old version
  • Silently stick with old version

Object References

Shareable object references can be aware of versioning in following ways:

1. Always use latest version of referenced object
2. Always stay at current version
3. Notify author of referenced object updates

In all of these cases, changes to referenced object do _not_ constitute changes to referenceing object.

Object change notifications

There are few ways to notify referrer about change of referenced object. When reference is made, referer choses what he wants.

Email notification

* Each change - an email
* Digest - user gets summary of changes in all objects once in a while

Special page

Special page which provides filtered summary of changes, i.e. for all objects referenced by given course.

Object Edit Flow

Logically object editing follows this pattern:

1. Edit Object action is requested. It creates a temporary copy of an object
2. User edits and saves the copy (it can be saved as many times as needed)
3. When user is satisfied he executes "Release" action. Minor/Versioned edit
   is a required parameter for edit action. Probably will be implemented as
   radio button, that does not have initial value set (to avoid user forgetting
   to decided what kind of edit is it)

Internally object editing translates to following:

1. Edit Object action is requested. It creates a new version of an object in unpublished state (not visible for anyone besides author(s)). 
2. Any child objects connections are copied from the prior version.
3. User edits and saves the copy (it can be saved as many times as needed)
4. When user is satisfied he executes "Publish" action. Object is switched to published state.
5. All the connections to the parent objects are processed. The action on every connection is performed as defined in version_policy field of the connection.

Minor/Versioned edit is a required parameter for edit action. Probably will be implemented as radio button, that does not have initial value set (to avoid user forgetting to decided what kind of edit is it)


UU will have clustering capability. It is not 100% clear what kind of clustering support we will have, and how it will be implemented at this point.

Both database and application server need to be scalable in order to maintain flexebility.

There is some rudimentary clustering support in PostgreSQL to the best of my knowledge, but I don't know anything about details, so that needs to be researched.

There is nothing currently built into CPPServ in terms of scalability, but few things are pretty easy to implement. For example, we could add load balancing support to the front-end module, which would allow us to distribute requests between CPPServ instances. It could track which request belongs to which session, and forward it accordingly.

Alternatively we could implement session state sharing, and then use some external load blancer like vserver.

Text Handling

Text in UU will be represented with a safe subset of XHTML for the most part. We might add few extensions, for inserting media, Math formulas (MathML? LaTeX?)

Text Editor

Editing will be done with TinyMCE. We'll have to write a plugin for TinyMCE, to provide simple UI-based access to multimedia objects.

We shall also provide simple plain-text editing ability for non-JS, or pure-text browsers.

On the backend, we will need a filter system, which would verify validity of the text according to the following criteria:

  • Only allowed XHTML tags are used
  • All media references are valid
  • All formulae are compileable

Sets of allowed tags and MM objects will depend on kind of text

Multimedia Objects

Once the validation is passed, list of media references will be extracted, and UMO parent-child relationships with corresponding media objects will be established.

Links to multimedia objects work just like any other umo links (new versions will notify owner or just auto-update. The only question here is if we want to auto-rewrite original object with new IDs when switching to new media object version, or if we want to make separate IDs for such links, which will be permanently preserved.


Final HTML should be cached. It would make sense to cache it at the time object is published, since published version is immutable.


On the back end, any rich text will be represented as XML, which will include subset of allowed HTML tags (perhaps configurable by administrator) and our special tags for embedding media. Whenever such text will be needed for display purposes, the theme will request it, passing in an object which implements ITextRenderer interface, providing functions for turning embedded objects into HTML tags (in fact they'll have to return corresponding sptk::CXmlElements).

Overall procedure will be as follows:

  • get root element of the text to render (does not have to be complete document)
  • call uu::util::parseText(), pass in the root and the renderer
  • parseText will go through all tags, applying the renderer as needed and will throw an exception if invalid tag is encountered.
  • parseText will serialize resulting XML tree into a string and return it.

Embedded media objects (images, flash, etc.) are stored as separate UMOs, and thus must be linked to the UMO being rendered, in order to be used. These objects are referenced in the text through base ID of the embedded UMO. When UMO is published, umo_to_parent_umo ID is supplemented in the text. This way all the normal rules for versioning and relations between UMO versions apply, and at the same time the need to keep track of media UMOs is reduced and the procedure is simplified.

Multimedia Handling


Actual media data will be stored on file system. In case we need more then one CPPSERV instance running, media files will be stored on some primary server, and then distributed to secondary servers later on. Once media file is distributed to some server, it will be reflected as such in database. Primary server is the one used by end user to upload the media file. When reference to given media file is needed, full URL will refer to same server CPPSERV is running on if database claims it's available, or to the primary server if not.


Following data will be stored in the database:

  • type of media (image, flash, etc.). Perhaps just mime type
  • file name
  • Usual UMO info
  • list of servers this image is on


There are two ways to handle translations:

  • Only translate title and description, but always refer to the same actual media file
  • Allow to translate everything

Description-only implementation

This one is simple - we make file name an UMO attribute. Everything else just takes care of itself

Fully translatable implementation

We could say that content of media object is XML, and keep all the metadata in there. In this case we could simply store different file names for different translations. The disadvantage of this approach is that we can't efficiently do a mapping from file name back to the UMO in database.


Instead of storing data on file system we could store whole thing in database. The problem with this approach is that PostgreSQL support for blobs is somewhat lacking.

Course sign-up

In order to study a course, student has to sign up for a class, which is signed up to study it.

Course record creation

Currently the study_course record is created when the course UMO is published.

Class creation

Class is created in the following cases:

  • New version of a course object is published

In this case a new class is created and signed up for this course automatically. It is marked as the default class for the course. The person who published the course is set as a teacher and admin of the class.

  • Someone decides they want to teach a class, and creates one

Class operations

Following operations can be performed on a class:

  • Teachers can be assigned
  • Students can request sign-up
  • Teachers can approve student requests
  • Administrators can be assigned

Signing up for a class

Classes have a "sign-up mode" attribute. It determines what is the process flow, in case a student requests to be signed up for a class. Regardless of the sign-up mode teacher may invite a student into a class, and the student will have an option of accepting the invitation.

100% free

In the simplest case student gets signed-up to a class as soon as he requests it.

Free moderated

  • Student requests sign-up
  • One of teachers approves it


  • Student requests sign-up
  • Student pays the fee

Paid moderated

  • Student requests sign-up
  • Student pays the fee
  • Teacher approves the request
  • In case request wasn't approved, student is credited his money back.

Note: For the time being paid modes will not be implemented. It is unclear how to pass the money on to teachers, and especially unclear how to make sure everyone gets their fair share in case a class is taught by more then one teacher.

Closed course

Student cannot request a sign up. Instead, teacher can send an invitation, which student can accept.

Behind the scenes

Internally, the following sequence of steps happens:

  • (Optional) Sign-up invitation from a teacher (invite_student)
  • Sign-up request: class_subscription_reserve function is called
  • class_subscription_reserve creates a new order (order_create)
  • class_subscription_reserve calls mode-specific handler (see Free, Free Moderated, Paid, Paid Moderated, Closed)
  • UI retrieves order status and amount owed by student
  • If amount is non-zero, UI offers student an option to pay, and, once payment is processed, calls "order_paid" and refreshes order status
  • If order status is "pending", the student gets the indication he should wait for approval from teacher.
  • Teacher gets a list of students who are ready to start studying (their orders are in "pending" state)
  • Teacher approves an order: class_subscription_confirm is called.
  • Student is ready to study.

Signing up class for a course

For the time being any class admin can simply sign up the class for any course. A class can be signed up for any number of courses, even to multiple versions of a same course.



While my personal view is that grading does more harm to education then it does good, grading does have its place within the system. Its primary role is not the educational one, but rather, it allows a third party (i.e. prospective employer) to gage student's success in studying, without an in-depth examination of student's activities during the process. To make that measure accurate, simple grading is obviously not enough. Some sort of feedback system to assign weight to different graders is needed as well, but that is something for the future. Meanwhile we need to get the basic grading framework in place.

Gradeable UMOs

Final grade for a course is determined by combination of successful completion of some tasks (solving problems, passing tests, etc.) and some sort of human factor (teachers). However it does not make sense to assign grades to each UMO. Clearly, problems and tests deserve grades, while explanations - clearly don't. On the other hand, topic may be gradeable or may be not.

Grading workflow

Base value and Formula

Grade assigned to a student for completing an object consists of base value modified by pre-set formula. For example: Let's say we have a test, with base grade 10, consisting of 10 problems, each with possible grades of 1 or 0, and simple fraction formula. Each problem, in turn, would have base value of 1, and simple pass/fail formula. Thus final grade for the test would be value from 1 to 10, with 1:1 mapping to the number of problems solved.

Another example: stand-alone human-controlled problem might have a base value of 100, and percentage formula. The percentage would be assigned by teacher verifying the solution. Or there may be "direct" formula, where base value is interpreted as maximum grade, and teacher simply specifies any value up to the maximum...

There are two types of gradeable objects - primary and derived. Primary types have grade directly associated with them. Derived get a grade based on grades assigned to child objects.

Both types of objects can be auto-graded or manually-graded (although even auto-generated grades can be adjusted by teacher).

In all cases final grade is a fraction of base value.

  • Auto-graded primary: Type-specific computation is performed by app server, and grade fraction is supplied to the database.
  • Teacher-graded primary: Completion data is supplied to the database
  • Auto-graded derived: Completion data is supplied, and class-specific function is called within database to calculate grade fraction.
  • Teacher-graded derived: Completion data is supplied.

UMO-grade-user relationships

Base grade and formula are configured by Class Administrators for each UMO for which the class is signed up. For simplifying this task we will provide a way to group them and mass-configure grades, but internally base values and formulae will still have to be configured per umo per class.

The final grade for the UMO for the student will be recorded per umo per student per class. This means that if student encounters same version of the same UMO in more then one class, his completion information will be stored only once, and he will not have to complete it again, yet grading records for each class he encounters UMO through will be separate.

Tracking class

While user is studying, system always keeps the concept of "current class". UMO simply cannot be studied without it. The flow is as follows:

Flow 1: Login -> Chose the class -> enter course -> navigate to UMO.
 Once Class is entered, it is recorded in current user's session
 When UMO is entered for the first time, the class it was entered through
 is recorded in the database
Flow 2: Login -> navigate directly to UMO
 If it's the first time access to the UMO, exception is thrown
 If it has been properly accessed through class before, current
 class is set from database.

User handling

Users in UU can have multiple roles, in respect do different UMOs. For the purpose of optimizing UI display performance, user object will have set of flags, which will indicate if the user has some role for at least one UMO. e.g. if user is a teacher of at least one class, if he created at least one UMO, if he is a student of at least one class currently. These flags will be adjusted every time user's ACL for some object is changed.