package org.thrudb.thrudoc;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.apache.log4j.Logger;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TMessage;
import org.apache.thrift.protocol.TMessageType;
import org.apache.thrift.protocol.TProtocol;
import org.thrudb.thrift.TPeekingTransport;
import org.thrudb.thrudoc.Thrudoc.Iface;
import org.thrudb.thrudoc.Thrudoc.Processor;
import tokyocabinet.HDB;
public class ThrudocLoggingProcessor extends Processor {
private Set<String> writeOps;
private Logger logger = Logger.getLogger(getClass());
public ThrudocLoggingProcessor(Iface iface) {
super(iface);
writeOps = new HashSet<String>();
writeOps.addAll(Arrays.asList(new String[]{
"create_bucket","delete_bucket","put",
"push_front","push_back","pop_front","pop_back",
"erase_at","insert_at","replace_at","incr","decr"
}));
}
@Override
public boolean process(TProtocol iprot, TProtocol oprot) throws TException {
TPeekingTransport peekTrans = (TPeekingTransport) iprot.getTransport();
TPeekingTransport writeTrans = (TPeekingTransport) oprot.getTransport();
//Just peek at the initial message
peekTrans.setRecording(true);
TMessage msg = iprot.readMessageBegin();
peekTrans.setRecording(false);
if(writeOps.contains(msg.name)){
logger.info("logging "+msg.name);
peekTrans.setLogging(true);
}
peekTrans.setReplayMode(true);
boolean result = super.process(iprot, oprot);
//only log operations that alter the db
if(writeOps.contains(msg.name)){
writeTrans.swapInWriteBuffer();
msg = oprot.readMessageBegin();
//dont log operations that caused an exceptions
if(msg.type == TMessageType.EXCEPTION){
peekTrans.rollback();
} else {
peekTrans.commit();
}
}
peekTrans.reset();
return result;
}
private void writeLog(byte[] logMessage){
}
}