package com.yiqiniu.easytrans; import java.util.List; import javax.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.util.Assert; import com.yiqiniu.easytrans.context.LogProcessContext; import com.yiqiniu.easytrans.datasource.TransStatusLogger; import com.yiqiniu.easytrans.log.TransactionLogWritter; import com.yiqiniu.easytrans.log.vo.Content; import com.yiqiniu.easytrans.log.vo.Content.ContentType; import com.yiqiniu.easytrans.log.vo.DemiLeftContent; import com.yiqiniu.easytrans.log.vo.DemiRightContent; import com.yiqiniu.easytrans.log.vo.LogCollection; /** * Keep eventually consistent based on logs */ public class ConsistentGuardian { private Logger LOG = LoggerFactory.getLogger(this.getClass()); @Resource private TransStatusLogger transChecker; @Resource private ApplicationContext applicationContext; @Resource private TransactionLogWritter writer; /** * eventually consistent processing for recover * @param logCollection all the logs in the current time */ public boolean process(LogCollection logCollection){ return process(new LogProcessContext(logCollection,writer,transChecker)); } /** * eventually consistent processing * @param logCtx */ public boolean process(LogProcessContext logCtx){ LogCollection logCollection = logCtx.getLogCollection(); //依次调用LOG对应的Processor //统计并发布SemiLog事件 //发布ProcessEnd事件 List<Content> orderedContents = logCollection.getOrderedContents(); for(int i = 0;i < orderedContents.size() ; i++){ Content content = orderedContents.get(i); //check log order Assert.isTrue(content.getcId() != null && content.getcId().equals(i + 1),"content list did not sort or contentId is null"); if(content instanceof DemiLeftContent){ logCtx.getDemiLogManager().registerLeftDemiLog((DemiLeftContent)content); }else if(content instanceof DemiRightContent){ logCtx.getDemiLogManager().registerRightDemiLog((DemiRightContent)content); } Class<? extends LogProcessor> proccessorClass = ContentType.getById(content.getLogType()).getProccessorClass(); if(proccessorClass == null){ if(LOG.isDebugEnabled()){ LOG.debug("processor not set,continue" + content); } continue; } LogProcessor processor = applicationContext.getBean(proccessorClass); if(!processor.logProcess(logCtx, content)){ LOG.warn( "log processor return false,end proccesing and retry later." + content); return false; } } if(!logCtx.getDemiLogManager().pubulishDemiLogEvent()){ LOG.warn("DemiLogEvent Process return false,end proccesing and retry later." + logCollection); } if(!logCtx.getProcessEndManager().publish()){ LOG.warn("End process return false,end proccesing and retry later." + logCollection); } //end and flush log logCtx.getLogCache().flush(true); return true; } }