All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.terracotta.modules.ehcache.store.TerracottaClusteredInstanceFactory Maven / Gradle / Ivy

Go to download

Ehcache is an open source, standards-based cache used to boost performance, offload the database and simplify scalability. Ehcache is robust, proven and full-featured and this has made it the most widely-used Java-based cache.

There is a newer version: 2.10.9.2
Show newest version
/*
 * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
 */
package org.terracotta.modules.ehcache.store;

import net.sf.ehcache.Ehcache;
import net.sf.ehcache.cluster.CacheCluster;
import net.sf.ehcache.config.CacheWriterConfiguration;
import net.sf.ehcache.config.Configuration;
import net.sf.ehcache.config.TerracottaClientConfiguration;
import net.sf.ehcache.event.CacheEventListener;
import net.sf.ehcache.management.event.ManagementEventSink;
import net.sf.ehcache.store.Store;
import net.sf.ehcache.store.TerracottaStore;
import net.sf.ehcache.terracotta.ClusteredInstanceFactory;
import net.sf.ehcache.transaction.SoftLockManager;
import net.sf.ehcache.transaction.TransactionIDFactory;
import net.sf.ehcache.util.ProductInfo;
import net.sf.ehcache.writer.writebehind.WriteBehind;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terracotta.modules.ehcache.ToolkitInstanceFactory;
import org.terracotta.modules.ehcache.ToolkitInstanceFactoryImpl;
import org.terracotta.modules.ehcache.async.AsyncConfig;
import org.terracotta.modules.ehcache.async.AsyncCoordinator;
import org.terracotta.modules.ehcache.async.AsyncCoordinatorFactory;
import org.terracotta.modules.ehcache.async.AsyncCoordinatorFactoryImpl;
import org.terracotta.modules.ehcache.event.ClusteredEventReplicatorFactory;
import org.terracotta.modules.ehcache.event.FireRejoinOperatorEventClusterListener;
import org.terracotta.modules.ehcache.event.TerracottaTopologyImpl;
import org.terracotta.modules.ehcache.management.ClusteredManagementEventSink;
import org.terracotta.modules.ehcache.store.nonstop.NonStopStoreWrapper;
import org.terracotta.modules.ehcache.transaction.ClusteredTransactionIDFactory;
import org.terracotta.modules.ehcache.transaction.SoftLockManagerProvider;
import org.terracotta.modules.ehcache.writebehind.AsyncWriteBehind;
import org.terracotta.modules.ehcache.writebehind.WriteBehindAsyncConfig;
import org.terracotta.toolkit.Toolkit;
import org.terracotta.toolkit.ToolkitFeatureTypeInternal;
import org.terracotta.toolkit.internal.ToolkitInternal;
import org.terracotta.toolkit.internal.feature.ManagementInternalFeature;
import org.terracotta.toolkit.internal.feature.NonStopInternalFeature;

import com.terracotta.entity.ehcache.EhcacheEntitiesNaming;

import java.util.concurrent.Callable;

public class TerracottaClusteredInstanceFactory implements ClusteredInstanceFactory {

  public static final Logger                    LOGGER                     = LoggerFactory
                                                                               .getLogger(TerracottaClusteredInstanceFactory.class);
  public static final String                    DEFAULT_CACHE_MANAGER_NAME = "__DEFAULT__";

  protected final ToolkitInstanceFactory        toolkitInstanceFactory;

  // private final fields
  protected final CacheCluster                  topology;
  private final ClusteredEventReplicatorFactory clusteredEventReplicatorFactory;
  private final SoftLockManagerProvider         softLockManagerProvider;
  private final AsyncCoordinatorFactory         asyncCoordinatorFactory;
  private final TerracottaStoreInitializationService      initializationService;

  public TerracottaClusteredInstanceFactory(TerracottaClientConfiguration terracottaClientConfiguration,
                                            ClassLoader loader) {
    toolkitInstanceFactory = createToolkitInstanceFactory(terracottaClientConfiguration, loader);
    initializationService = new TerracottaStoreInitializationService(toolkitInstanceFactory.getToolkit().getClusterInfo());
    topology = createTopology(toolkitInstanceFactory);
    clusteredEventReplicatorFactory = new ClusteredEventReplicatorFactory(toolkitInstanceFactory);
    softLockManagerProvider = new SoftLockManagerProvider(toolkitInstanceFactory);
    asyncCoordinatorFactory = createAsyncCoordinatorFactory();
    logEhcacheBuildInfo();
  }

  private static CacheCluster createTopology(ToolkitInstanceFactory factory) {
    TerracottaTopologyImpl cacheCluster = new TerracottaTopologyImpl(factory.getToolkit().getClusterInfo());
    try {
      cacheCluster.addTopologyListener(new FireRejoinOperatorEventClusterListener(factory));
    } catch (Exception e) {
      LOGGER.warn("Unable to register: " + FireRejoinOperatorEventClusterListener.class.getName(), e);
    }
    return cacheCluster;
  }

  private void logEhcacheBuildInfo() {
    final ProductInfo ehcacheCoreProductInfo = new ProductInfo();
    // ToolkitLogger logger = ((ToolkitInternal) toolkitInstanceFactory.getToolkit())
    // .getLogger(TerracottaClusteredInstanceFactory.class.getName());
    LOGGER.info(ehcacheCoreProductInfo.toString());
  }

  protected ToolkitInstanceFactory createToolkitInstanceFactory(TerracottaClientConfiguration terracottaClientConfiguration,
                                                                ClassLoader loader) {
    return new ToolkitInstanceFactoryImpl(terracottaClientConfiguration, loader);
  }

  protected AsyncCoordinatorFactory createAsyncCoordinatorFactory() {
    return new AsyncCoordinatorFactoryImpl(toolkitInstanceFactory);
  }

  @Override
  public final Store createStore(Ehcache cache) {
    return new ClusteredSafeStore(newStore(cache));
  }

  protected ClusteredStore newStore(final Ehcache cache) {
    return new ClusteredStore(toolkitInstanceFactory, cache, topology);
  }

  @Override
  public final TerracottaStore createNonStopStore(Callable store,
 Ehcache cache) {
    return new NonStopStoreWrapper(store, toolkitInstanceFactory, cache, initializationService);
  }

  @Override
  public CacheCluster getTopology() {
    return topology;
  }

  @Override
  public WriteBehind createWriteBehind(Ehcache cache) {
    final CacheWriterConfiguration config = cache.getCacheConfiguration().getCacheWriterConfiguration();
    final AsyncConfig asyncConfig = new WriteBehindAsyncConfig(config.getMinWriteDelay() * 1000,
                                                               config.getMaxWriteDelay() * 1000,
                                                               config.getWriteBatching(), config.getWriteBatchSize(),
                                                               cache.getCacheConfiguration()
                                                                   .getTerracottaConfiguration().isSynchronousWrites(),
                                                               config.getRetryAttempts(),
                                                               config.getRetryAttemptDelaySeconds() * 1000,
                                                               config.getRateLimitPerSecond(),
                                                               config.getWriteBehindMaxQueueSize());

    final AsyncCoordinator asyncCoordinator = asyncCoordinatorFactory.getOrCreateAsyncCoordinator(cache, asyncConfig);
    return new AsyncWriteBehind(asyncCoordinator, config.getWriteBehindConcurrency());
  }

  @Override
  public synchronized CacheEventListener createEventReplicator(Ehcache cache) {
    return clusteredEventReplicatorFactory.getOrCreateClusteredEventReplicator(cache);
  }

  /**
   * This is used by SampledMBeanRegistrationProvider to generate a JMX MBean ObjectName containing the client's uuid so
   * that it can be associated with the correct connection when tunneled to the L2.
   */
  @Override
  public String getUUID() {
    return ((ToolkitInternal) toolkitInstanceFactory.getToolkit()).getClientUUID();
  }

  @Override
  public void enableNonStopForCurrentThread(boolean enable) {
    NonStopInternalFeature nonStopInternalFeature = ((ToolkitInternal)toolkitInstanceFactory.getToolkit()).getFeature(ToolkitFeatureTypeInternal.NONSTOP);
    if (nonStopInternalFeature != null) {
      nonStopInternalFeature.enableForCurrentThread(enable);
    }
  }

  @Override
  public void shutdown() {
    toolkitInstanceFactory.shutdown();
    initializationService.shutdown();
  }

  @Override
  public TransactionIDFactory createTransactionIDFactory(String uuid, String cacheManagerName) {
    return new ClusteredTransactionIDFactory(uuid, cacheManagerName, toolkitInstanceFactory, topology);
  }

  @Override
  public SoftLockManager getOrCreateSoftLockManager(Ehcache cache) {
    return softLockManagerProvider.getOrCreateClusteredSoftLockFactory(cache);
  }

  @Override
  public boolean destroyCache(final String cacheManagerName, final String cacheName) {
    boolean destroyed = toolkitInstanceFactory.destroy(cacheManagerName, cacheName);
    destroyed |= asyncCoordinatorFactory.destroy(cacheManagerName, cacheName);
    return destroyed;
  }

  @Override
  public void linkClusteredCacheManager(String cacheManagerName, Configuration configuration) {
    toolkitInstanceFactory.linkClusteredCacheManager(cacheManagerName, configuration);
  }

  @Override
  public void unlinkCache(String cacheName) {
    try {
      toolkitInstanceFactory.unlinkCache(cacheName);
    } catch (RuntimeException e) {
      if(e.getClass().getSimpleName().equals("TCNotRunningException")) {
        LOGGER.info("Terracotta client already shutdown", e);
      } else {
        throw e;
      }
    }
  }

  @Override
  public ManagementEventSink createEventSink() {
    Toolkit toolkit = toolkitInstanceFactory.getToolkit();
    ToolkitInternal toolkitInternal = (ToolkitInternal)toolkit;
    ManagementInternalFeature feature = toolkitInternal.getFeature(ToolkitFeatureTypeInternal.MANAGEMENT);
    return new ClusteredManagementEventSink(feature);
  }

  public static String getToolkitMapNameForCache(String cacheManagerName, String cacheName) {
    return EhcacheEntitiesNaming.getToolkitCacheNameFor(cacheManagerName, cacheName);
  }

  @Override
  public void waitForOrchestrator(String cacheManagerName) {
    toolkitInstanceFactory.waitForOrchestrator(cacheManagerName);

  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy