package com.yiqiniu.easytrans.executor;
import java.io.Serializable;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.yiqiniu.easytrans.EasyTransSynchronizer;
import com.yiqiniu.easytrans.RemoteServiceCaller;
import com.yiqiniu.easytrans.context.LogProcessContext;
import com.yiqiniu.easytrans.context.event.GuardianProcessEndEventHandler;
import com.yiqiniu.easytrans.protocol.BusinessIdentifer;
import com.yiqiniu.easytrans.protocol.EasyTransRequest;
import com.yiqiniu.easytrans.protocol.IdempotentTypeDeclare.TransactionId;
import com.yiqiniu.easytrans.protocol.msg.PublishResult;
import com.yiqiniu.easytrans.serialization.ObjectSerializer;
import com.yiqiniu.easytrans.util.ReflectUtil;
public class BestEffortMessageMethodExecutor implements EasyTransExecutor{
@Resource
private EasyTransSynchronizer transSynchronizer;
@Resource
private RemoteServiceCaller publisher;
@Resource
private ObjectSerializer serialization;
private Logger LOG = LoggerFactory.getLogger(this.getClass());
@SuppressWarnings("unchecked")
@Override
public <P extends EasyTransRequest<R,E>,E extends EasyTransExecutor,R extends Serializable> Future<R> execute(final P params) {
FutureTask<PublishResult> future = new FutureTask<PublishResult>(new Callable<PublishResult>() {
@Override
public PublishResult call() throws Exception {
return new PublishResult();//do nothing
}
});
future.run();
final LogProcessContext logProcessContext = transSynchronizer.getLogProcessContext();
//sent message after transaction commit
logProcessContext.registerProcessEndEventListener(new GuardianProcessEndEventHandler() {
@Override
public boolean beforeProcessEnd(LogProcessContext logContext) {
if(logProcessContext.getFinalMasterTransStatus()){
BusinessIdentifer businessIdentifer = ReflectUtil.getBusinessIdentifer(params.getClass());
String messageId = getMessageId("M" + logProcessContext.getAndIncTransUniqueId(), logContext.getTransactionId());
publisher.publish(businessIdentifer.appId(), businessIdentifer.busCode(), messageId, params,logProcessContext);
LOG.info("Best effort message sent." + messageId);
}
return true;
}
});
return (Future<R>) future;
}
private String getMessageId(String innerId, TransactionId parentTrxId) {
return parentTrxId.getAppId()+"|"+parentTrxId.getBusCode()+"|"+parentTrxId.getTrxId()+"|"+innerId;
}
}