Log as a Service (Part 1 of 2)

Last week I introduced some of the hype behind our new project: Laasie.  This week, let me delve into some of the technical details.  Although for simplicity, I'll be using the present tense, please keep in mind that what I'm about to describe is work in progress.  We're hard at work implementing these, and will release when-it's-ready (tm blizzard entertainment).  

So, let's get to it.  There are two state abstractions in Laasie: state land, and log land.  I'll address each of these independently.

State Land

State land is what application developers interact with directly, and is most easily thought of as a big JSON object.  Those familiar with MongoDB, Pig Latin, or JaQL should feel right at home here.  However, Laasie provides a powerful set of abstractions for developing collaborative web applications.  That is, although it has a RESTful API, Laasie's true power lies in its state replication and programatic update features.  Let's see what they can do.


In a normal REST API, reads are performed by a client specifying a key (or equivalently a path) of interest.  The infrastructure obtains the key, passes it to the client, and the interaction is complete.  

Object read(path)

Laasie on the other hand, is designed for state replication.  In the Laasie model, reads operate (conceptually) in three stages:

  1. When a client first connects, it requests a session token by providing a path of interest and any relevant authentication tokens (e.g., username/password).  
  2. Using the session token, the client initializes its state.  This is analogous to a RESTful read, except that the requested value is returned along with a state token (effectively a timestamp).
  3. Using its session and state tokens, a client can request an update: a javascript function that, if executed, will transform one version of the state into the next.  This returns a new session token.
SessionTok createSession(path, client_identity)
{Object, StateTok} initSession(SessionTok)
{function(x) -> newx, StateTok} updateSession(SessionTok, StateTok)

The update function is typically going to be smaller than reading the entire state from scratch, making this an ideal way to keep a clients up-to-date.  Also note that we can use blocking HTTP requests to support PULL-style functionality in updateSession, while keeping control over updates in the hands of the client.  This is crucial for disconnect-heavy settings like mobile computing, where browser-based apps are extremely common.

We plan to develop client-side libraries (e.g., in Javascript) to simplify the task of state maintenance.  Such a library will essentially maintain a local copy of the requested object and manage updates. 


Like reads, Laasie exposes a more powerful write API.  Laasie allows developers to express updates as functions.  Although we expect many of these functions to be simple (overwrite value X, add 2 to value Y), the API is actually quite powerful, and we plan to add more features, domain-specific extensions and DSLs over time.  The full extend of this language is more than I want to get into in this post, but if you're familiar with Pig Latin or JaQL, you should feel right at home.  

An important feature of Laasie is that these update functions are transmitted and stored as-is in Laasie (Laasie doesn't typically evaluate them).  Instead, Laasie uses the update's semantics to identify and evaluate potential optimizations.  Next week, I'll get into how Laasie does this, and show how infrastructure managers can use Laasie's second abstraction: log land, to extend Laasie's optimization capabilities with application-specific optimizations.