Tuesday, March 13, 2012

Using Thrift in Coherence

Coherence provides you two built-in options for serialization format for your object: Java serialization and POF. But you are not limited to this option. You can totally different way of serialization using custom Serializer.

Why use alternative serialization?

If you think that Thrift or Protobuf would be better in speed or size compared to POF, that is probably not true. I did a benchmark using this framework, POF was scoring slightly better than both Thrift and Protobuf. In addition, POF can extract attributes without deserialization of whole object.
Only serious reason I can think of – you already alternative serialization implemented for you object and do not want support multiple format. If it is your can, using alternative serialization in Coherence is perfectly justified.

Catch

So you already have, serialization format for your domain objects you are happy this. But besides domain objects, you custom serializer should also support: standard java types (including collections), internal Coherence classes and custom entry processors, aggregations, filter use by your application (if any). So, custom serializer is not a practical option.

Hybrid POF + Thrift serializer

Solution is simple; use your alternative format for domain objects and POF for anything else. Here is example using Thrift.
pof-config.xml
<pof-config>
 
    <user-type-list>
 
        <!-- Include definitions required by Coherence -->
        <include>coherence-pof-config.xml</include>
 
        <!--
            You should declare type ID for each thrift class you are going to use in Coherence
        -->
        <user-type>
            <type-id>1000</type-id>
            <class-name>org.gridkit.sample.MyObject</class-name>
            <serializer>
                <class-name>org.gridkit.coherence.utils.thift.ThriftPofSerializer</class-name>
            </serializer>
        </user-type>
 
        ...
 
        <!-- Usual POF declarion for application non-thrift classes -->
 
        <user-type>
            <type-id>1100</type-id>
            <class-name>org.gridkit.coherence.sample.SampleEntryProcessor</class-name>
        </user-type>
           
    </user-type-list>
        
</pof-config>
ThriftPofSerializer.java
public class ThriftPofSerializer implements PofSerializer {

 private Constructor<?> constructor;
 private TSerializer serializer;
 private TDeserializer deserializer;
 
 
 public ThriftPofSerializer(int typeId, Class type) {
  try {
   this.constructor = type.getConstructor();
   this.constructor.setAccessible(true);
   this.serializer = new TSerializer();
   this.deserializer = new TDeserializer();
  } catch (Exception e) {
   throw new RuntimeException(e);
  }
 }

 @Override
 @SuppressWarnings("rawtypes")
 public void serialize(PofWriter out, Object obj) throws IOException {
  TBase tobj = (TBase) obj;
  byte[] data;
  try {
   data = serializer.serialize(tobj);
  } catch (TException e) {
   throw new IOException(e);
  }
  out.writeBinary(0, new Binary(data));
 }

 @Override
 @SuppressWarnings("rawtypes")
 public Object deserialize(PofReader in) throws IOException {
  try {
   byte[] data = in.readByteArray(0);
   TBase stub = (TBase) constructor.newInstance();
   deserializer.deserialize(stub, data);
   return stub;
  } catch (Exception e) {
   throw new IOException(e);
  }
 }
}
If some Thrift class in used by other Thrift classes but do not put in Coherence individually, you can omit it in pof-config.xml.

No comments:

Post a Comment