8000 org.corfudb.runtime.smr · CorfuDB/CorfuDB Wiki · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

org.corfudb.runtime.smr

Dahlia Malkhi edited this page May 2, 2015 · 4 revisions

A State-Machine-Replication (SMR) layer provides transparent object replication. An object is replicated by inflicting all object accesses through an SMR. The basic API of an SMR engine is defined in ISMREngine, and a direct log-based implementation is provided in a template class SimpleSMREngine<T>.

ISMREngine defines two fundamental functionalities.

  1. propose takes as parameter a lambda function captured inside an ISMREngineCommand object, and appends it to the stream. To mutate a replicated object state, user code needs to propose the update through the ISMREngine.propose method.

  2. sync plays back the sequence of SMR updates, which are each applied to the in-memory state. To access the in-memory state of a replicated object, user code should first invoke sync.

Below is a recipe for transforming a user's custom-made class into a replicated object via ISMREngine. To be concrete, consider a MyMap object with two methods, get and put.

class Map<T> {

    MyMap<T>() { .. }

    public void put(<T> param1) { .. }

    public <T> get(param2) { .. }

}
  1. Inside the constructor, instantiate an SMREngine object over a stream.

     MyMap<T>() { 
         smrEngine = new SimpleSMREngine(streamID, MyMap<T>.class); 
     }
    
  2. Turn object methods private.

     private void pPut(<T> param1) { .. }
    
     private <T> pGet(param2) { .. }
    
  3. Capture mutating-methods as lambdas. This lambda is a BiConsumer, which takes the object the command is to act on, and an options object. You'll need to cast the lambda into a ISMREngineCommand, otherwise the lambda won't be serializable and your object won't work! ISMREngineCommand<MyMap> mapPut = (ISMREngineCommand<MyMap>) (a,opt) -> a.pPut(opt);

  4. Re-define the public mutator-methods to propose the corresponding update:

     void put(<T> obj) {
         smrEngine.propose(mapPut, obj);
     }
    
  5. Turn reading methods to first invoke SMREngine.sync.

     public <T> get(param2) { 
         smrEngine.sync();
         return pGet(param2);
     }
    

An interesting use case to consider is an object method that contains conditional writes, such as a test-and-modify. In order to apply the compound operation, we need to wait until a log position is determined, play back the log, and then apply the operation. The recommended way to implement this, which uses Java runtime futures, is exemplified in the CorfuDB tutorial example.

Clone this wiki locally
0