package com.bagri.xdm.cache.coherence.process; import com.tangosol.net.AbstractInvocable; import com.tangosol.net.CacheFactory; import com.tangosol.net.InvocationService; import com.tangosol.net.Member; import com.tangosol.net.MemberEvent; import com.tangosol.net.MemberListener; import com.tangosol.net.Service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Collections; import java.util.List; import java.util.Set; /** * Cache population listener * User: dsukhoroslov * Date: 16.07.12 21:10 */ public class CachePopulationListener implements MemberListener { private static final String POPULATION_SERVICE_NAME = "PopulationService"; private final Logger log = LoggerFactory.getLogger(getClass()); private int size = 1; private InvocationService popService; private List<AbstractPopulator> populators; /** * Class constructor */ public CachePopulationListener() { this(1, POPULATION_SERVICE_NAME); log.trace("Cache Member Listener instantiated from zero-arg constructor"); } /** * Class constructor * * @param clusterSize Cluster size * @param invocationServiceName Invocation service name */ public CachePopulationListener(int clusterSize, String invocationServiceName) { size = clusterSize; popService = (InvocationService) CacheFactory.getService(invocationServiceName); log.trace("Cache Member Listener instantiated with size: {} and population service: {}", size, invocationServiceName); } /** * Class constructor * * @param clusterSize Cluster size * @param invocationService Invocation service */ public CachePopulationListener(int clusterSize, InvocationService invocationService) { size = clusterSize; popService = invocationService; log.trace("Cache Member Listener instantiated with size: {} and population service: {}", size, invocationService); } public int getClusterSize() { return size; } public String getPopulationService() { if (popService != null) { return popService.getInfo().getServiceName(); } return POPULATION_SERVICE_NAME; } public List<AbstractPopulator> getPopulators() { return Collections.unmodifiableList(populators); } public AbstractPopulator getPopulator(String cacheName) { for (AbstractPopulator pop: populators) { if (cacheName.equals(pop.getCacheName())) { return pop; } } return null; } /** * @param populators Populator list */ public void setPopulators(List<AbstractPopulator> populators) { this.populators = populators; log.debug("Got populators: {}", populators.size()); } //private PopulationContext newContext() { // //} /** * @param event Member event */ @Override public void memberJoined(MemberEvent event) { log.trace("Cache member joined: {}", event); final Service service = event.getService(); Object ctx = service.getUserContext(); log.debug("memberJoined; got Context: {} on service: {}", ctx, service.getInfo().getServiceType()); PopulationContext popCtx; if (ctx != null) { popCtx = (PopulationContext) ctx; } else { popCtx = new PopulationContext(size); try { service.setUserContext(popCtx); } catch (RuntimeException ex) { log.error("Exception assigning context: ", ex); } } int cnt = popCtx.joinService(); log.debug("memberJoined; join count: {}", cnt); if (popCtx.isReadyToPopulate()) { log.debug("memberJoined; starting population"); Member local = service.getCluster().getLocalMember(); Set<Member> localSet = Collections.singleton(local); log.debug("memberJoined; Starting population on member: {}", local); for (AbstractPopulator pop : populators) { try { startPopulation(pop, localSet); } catch (Exception ex) { log.error("Exception populating cache: {}", pop.getCacheName(), ex); } } log.debug("memberJoined; All ({}) populators were started", populators.size()); } else { log.debug("memberJoined; not ready to populate yet"); } } public void startPopulation(AbstractPopulator populator) { Member local = popService.getCluster().getLocalMember(); Set<Member> localSet = Collections.singleton(local); startPopulation(populator, localSet); } protected void startPopulation(AbstractPopulator populator, Set<Member> members) { popService.execute(populator, members, null); log.trace("{} cache population has been started an {} members", populator.getCacheName(), members.size()); } /** * @param event Member event */ @Override public void memberLeaving(MemberEvent event) { log.trace("Cache member leaving: {}", event); } /** * @param event Member event */ @Override public void memberLeft(MemberEvent event) { log.trace("Cache member left: {}", event); Object ctx = event.getService().getUserContext(); log.debug("memberLeft; got Context: {}", ctx); if (ctx != null) { PopulationContext popCtx = (PopulationContext) ctx; popCtx.leaveService(); } } }