Backend - Editor technical guide
All the code related to the concurrent editing feature of the CMS is stored within the Backend/editor
folder, this article just serves as a bit of a technical guide so that the code becomes a bit easier to understand .
Overview
The code is split into two primary parts editor/service
and editor/document
, the document directory defines core data structures for the editor, namely the document and extension data structures. The document data structure is responsible for maintaining a global document state, shadow states for all connected extensions and modifying the global state based on the requests of extensions.
The extension data structure’s purpose is a bit more ill-defined, the extension data structure is any developer defined operation we may want to perform on the global document, examples of such operations include automatically saving a document to memory every n minutes, exposing a document to clients outside of the system via web sockets (allowing them to also edit send updates to the document), real time analytics, duplication detection, etc (really anything you want ).
Documents
I’ll provide a bit more information regarding extensions later but first if you haven’t already please read the “differential synchronization” paper by Niel Fraser. The document data structure works in an event loop responding to certain events, there are only really 2 key events that it responds to: a synchronization event and a termination event. When the document data structure is created it goes through all its initialization steps defined in the newDocument
method, the calling function then calls document.spin()
as a go-routine, the spin method is rather simple and is just a go-routine spinning in a for loop, this spin method is our main event loop. To achieve a “event-driven“ program in Go the document data structure maintains 2 channels, a termination channel and a synchronization channel (if you’re unfamiliar with channels they basically buffered queues that block on read). If the document receives a message on the termination channel it exists its event loop otherwise it keeps listening for information on the synchronization channel.
If it receives information on the sync channel it will perform all the required steps in the differential synchronization algorithm .
Extensions
Extensions (I should probably rename this) represent some functionality we want to perform on a document, extensions send signals to the document via the synchronization channel allowing them to “push“ changes to the document or receive upstream changes. Extensions are also programed in an event drive manner and there are 3 main events in their lifecycle:
Initialization
Synchronization
Destruction
Since events have to be attached to a document via the document.addExtension
method whenever an extension is attached the document calls its init method and gives it the communication channel it will use to send updates to the document, as well as the current state of the document. The synchronization event is the event that the document triggers when there are updates to its state that it must push to all connected extensions, this even is in essence an implementation of the differential synchronization algorithm.
Service and Broker
The service
directory contains the broker type, the broker type can be thought as the main entrance to the editor and its primary purpose is to start/open documents via the document manager and load the required extensions on certain events, the broker exists to make it super easy to extend the current functionality of the editor. There are two key events the broker responds to newConn
and newDoc
, the first is the event that is triggered when an external client tries to open a document that's already spinning, when this happens the broker will connected the client and load the extensions listed in the newConn
array, a similar thing happens for the newDoc
event except it loads everything in the newDoc
array. The rest of the service directory contains any extension that we define.
Extending Functionality
The editor package is designed so that its super simple to extend its functionality, functionality extension happens in the form of a new extension, see the service directory on Github for some examples. TODO: Write a proper article.
Related content
UNSW CSESoc