package com.easyooo.framework.cache.transaction; import java.util.ArrayList; import java.util.Collection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.easyooo.framework.cache.storage.JVMCache; import com.easyooo.framework.support.redis.RedisTemplate; import com.easyooo.framework.support.transaction.RemoteSenderMorly; /** * 缓存批量发送器,将缓存一次性写入目标服务器 * * @author Killer */ public class BufferedCacheRemoteSender implements RemoteSenderMorly<Command>{ private final Logger logger = LoggerFactory.getLogger(getClass()); private static final String PROVIDER = "EASYOOO_CACHE"; /** 依赖外部注入 */ private RedisTemplate redisTemplate; /** 依赖外部注入 */ private UpdateCommandProducer updateCommandProducer; /** 本地缓存引用,for lock */ private final JVMCache jvmCacheObj = new JVMCache(); public BufferedCacheRemoteSender(RedisTemplate redisTemplate, UpdateCommandProducer updateCommandProducer){ this.redisTemplate = redisTemplate; this.updateCommandProducer = updateCommandProducer; } @Override public String getProviderInfo() { return PROVIDER; } @Override public boolean send(Collection<Command> commands) throws Exception { // 提取出JVM本地命令及redis缓存命令 Collection<Command> jvmCommands = new ArrayList<>(); Collection<Command> redisCommands = new ArrayList<>(); for (Command cmd : commands) { switch (cmd.getLevel()) { case JVM: jvmCommands.add(cmd); break; case REDIS: redisCommands.add(cmd); break; case JVM_TO_REDIS: jvmCommands.add(cmd); redisCommands.add(cmd); break; default: break; } } // send redis cache DefaultRedisTransactionCallback drtc = new DefaultRedisTransactionCallback( redisCommands); // send jvm cache DefaultJvmCacheTransactionCallback djt = new DefaultJvmCacheTransactionCallback(jvmCacheObj.getCacheObject(), jvmCommands); // lock cache object int jSize = jvmCommands.size(), rRize = redisCommands.size(); if(jSize > 0 && rRize > 0){ synchronized (jvmCacheObj.getCacheObject()) { synchronized (redisTemplate) { try{ redisTemplate.transaction(drtc); }catch(UnsupportedOperationException e){ redisTemplate.pipelined(drtc); } djt.doCallback(); } } }else if(jSize == 0 && rRize > 0) { synchronized (redisTemplate) { try{ redisTemplate.transaction(drtc); }catch(UnsupportedOperationException e){ redisTemplate.pipelined(drtc); } } }else if(jSize > 0 && rRize == 0){ synchronized (jvmCacheObj.getCacheObject()) { djt.doCallback(); } }else{ logger.info("No command to submit."); } // update to the other jvm process updateCommandProducer.submitUpdate(jvmCommands); return true; } }