[jbosscache-commits] JBoss Cache SVN: r6524 - in core/trunk/src: main/java/org/jboss/cache/interceptors and 4 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Tue Aug 5 20:57:16 EDT 2008


Author: manik.surtani at jboss.com
Date: 2008-08-05 20:57:16 -0400 (Tue, 05 Aug 2008)
New Revision: 6524

Added:
   core/trunk/src/test/java/org/jboss/cache/api/mvcc/PersistingTransientStateTest.java
   core/trunk/src/test/java/org/jboss/cache/optimistic/PersistingTransientStateTest.java
   core/trunk/src/test/java/org/jboss/cache/statetransfer/PersistingTransientStateTest.java
Modified:
   core/trunk/src/main/java/org/jboss/cache/config/Option.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferIntegrator.java
   core/trunk/src/main/java/org/jboss/cache/statetransfer/LegacyStateTransferIntegrator.java
   core/trunk/src/main/java/org/jboss/cache/statetransfer/LegacyStateTransferManager.java
Log:
JBCACHE-131 - persist transient state during state transfer under certain conditions

Modified: core/trunk/src/main/java/org/jboss/cache/config/Option.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/config/Option.java	2008-08-06 00:56:02 UTC (rev 6523)
+++ core/trunk/src/main/java/org/jboss/cache/config/Option.java	2008-08-06 00:57:16 UTC (rev 6524)
@@ -33,6 +33,7 @@
    private int groupRequestMode = -1;
 
    private int lockAcquisitionTimeout = -1;
+   private boolean suppressPersistence;
 
    /**
     * @since 1.4.0
@@ -303,6 +304,7 @@
       if (forceAsynchronous != option.forceAsynchronous) return false;
       if (forceSynchronous != option.forceSynchronous) return false;
       if (lockAcquisitionTimeout != option.lockAcquisitionTimeout) return false;
+      if (suppressPersistence != option.suppressPersistence) return false;
       return true;
    }
 
@@ -320,6 +322,7 @@
       result = 29 * result + (forceAsynchronous ? 0 : 1);
       result = 29 * result + (forceSynchronous ? 0 : 1);
       result = 29 * result + (lockAcquisitionTimeout);
+      result = 29 * result + (suppressPersistence ? 0 : 1);
       return result;
    }
 
@@ -338,6 +341,7 @@
       this.forceAsynchronous = false;
       this.forceSynchronous = false;
       this.lockAcquisitionTimeout = -1;
+      this.suppressPersistence = false;
    }
 
    /**
@@ -426,4 +430,26 @@
    {
       this.groupRequestMode = groupRequestMode;
    }
+
+   /**
+    * If set to true, any persistence to a cache loader will be suppressed for the current invocation only.  Does not apply to transactional calls.
+    *
+    * @return true if persistence is suppressed.
+    * @since 3.0
+    */
+   public boolean isSuppressPersistence()
+   {
+      return suppressPersistence;
+   }
+
+   /**
+    * If set to true, any persistence to a cache loader will be suppressed for the current invocation only.  Does not apply to transactional calls.
+    *
+    * @param suppressPersistence if true, will suppress persistence.
+    * @since 3.0
+    */
+   public void setSuppressPersistence(boolean suppressPersistence)
+   {
+      this.suppressPersistence = suppressPersistence;
+   }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java	2008-08-06 00:56:02 UTC (rev 6523)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java	2008-08-06 00:57:16 UTC (rev 6524)
@@ -86,7 +86,7 @@
    @Override
    public boolean skipInterception(InvocationContext ctx, VisitableCommand command)
    {
-      if (!ctx.isOriginLocal() && loaderConfig.isShared())
+      if ((!ctx.isOriginLocal() && loaderConfig.isShared()) || ctx.getOptionOverrides().isSuppressPersistence())
       {
          if (trace)
             log.trace("Passing up method call and bypassing this interceptor since the cache loader is shared and this call originated remotely.");

Modified: core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferIntegrator.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferIntegrator.java	2008-08-06 00:56:02 UTC (rev 6523)
+++ core/trunk/src/main/java/org/jboss/cache/statetransfer/DefaultStateTransferIntegrator.java	2008-08-06 00:57:16 UTC (rev 6524)
@@ -12,11 +12,10 @@
 import org.jboss.cache.CacheSPI;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.InternalNode;
-import org.jboss.cache.NodeFactory;
-import org.jboss.cache.Region;
+import org.jboss.cache.Node;
+import org.jboss.cache.NodeSPI;
 import org.jboss.cache.buddyreplication.BuddyManager;
-import org.jboss.cache.eviction.EvictedEventNode;
-import org.jboss.cache.eviction.NodeEventType;
+import org.jboss.cache.config.Configuration;
 import org.jboss.cache.factories.annotations.Inject;
 import org.jboss.cache.factories.annotations.Start;
 import org.jboss.cache.invocation.InvocationContext;
@@ -42,24 +41,25 @@
    private static final Log log = LogFactory.getLog(DefaultStateTransferIntegrator.class);
    private static final boolean trace = log.isTraceEnabled();
 
-   private CacheSPI cache;
+   private CacheSPI<?, ?> cache;
 
-   private NodeFactory factory;
-
    private Set<Fqn> internalFqns;
+   private Configuration cfg;
+   private boolean needToPersistState;   // for JBCACHE-131
 
-
    @Inject
-   public void inject(CacheSPI<?, ?> cache, NodeFactory nodefactory)
+   public void inject(CacheSPI<?, ?> cache, Configuration cfg)
    {
       this.cache = cache;
-      this.factory = nodefactory;
+      this.cfg = cfg;
    }
 
    @Start(priority = 14)
    public void start()
    {
       this.internalFqns = cache.getInternalFqns();
+      needToPersistState = cfg.getCacheLoaderConfig() != null && !cfg.getCacheLoaderConfig().isFetchPersistentState() &&
+            !cfg.getCacheLoaderConfig().isShared();
    }
 
    public void integrateState(ObjectInputStream ois, Object target, Fqn targetRoot, boolean integratePersistentState) throws Exception
@@ -86,7 +86,7 @@
             log.trace("integrating transient state for " + target);
          }
 
-         integrateTransientState(target, in);
+         integrateTransientState(target.getFqn(), in);
 
          transientSet = true;
 
@@ -189,10 +189,23 @@
       for (InternalNode n : children) notifyAllNodesCreated(ctx, n);
    }
 
-   private void integrateTransientState(InternalNode target, ObjectInputStream in) throws Exception
+   private void prepareContextOptions()
    {
-      target.removeChildren();
+      cache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
+      cache.getInvocationContext().getOptionOverrides().setSkipCacheStatusCheck(true);
+      cache.getInvocationContext().getOptionOverrides().setSuppressPersistence(!needToPersistState);
+   }
 
+   private void integrateTransientState(Fqn target, ObjectInputStream in) throws Exception
+   {
+      prepareContextOptions();
+      NodeSPI targetNode = cache.getNode(target);
+      for (Object childname : targetNode.getChildrenNames())
+      {
+         prepareContextOptions();
+         targetNode.removeChild(childname);
+      }
+
       List<NodeData> list = readNodesAsList(in);
       if (list != null)
       {
@@ -207,18 +220,20 @@
             //are there any transient nodes at all?
             if (nd != null && !nd.isMarker())
             {
-               Map attributes = nd.getAttributes();
+               // with MVCC these calls should ALWAYS go up the interceptor chain since no other locking
+               // takes place elsewhere.
+               prepareContextOptions();
+               cache.clearData(target);
+               prepareContextOptions();
+               cache.put(target, nd.getAttributes());
 
-               target.setInternalState(attributes);
-
                // Check whether this is an integration into the buddy backup
                // subtree
                Fqn tferFqn = nd.getFqn();
-               Fqn tgtFqn = target.getFqn();
-               boolean move = tgtFqn.isChildOrEquals(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN)
-                     && !tferFqn.isChildOrEquals(tgtFqn);
+               boolean move = target.isChildOrEquals(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN)
+                     && !tferFqn.isChildOrEquals(target);
                // If it is an integration, calculate how many levels of offset
-               int offset = move ? tgtFqn.size() - tferFqn.size() : 0;
+               int offset = move ? target.size() - tferFqn.size() : 0;
 
                integrateStateTransferChildren(target, offset, nodeDataIterator);
 
@@ -240,11 +255,11 @@
       return (List<NodeData>) obj;
    }
 
-   private NodeData integrateStateTransferChildren(InternalNode parent, int offset, Iterator<NodeData> nodeDataIterator)
+   private NodeData integrateStateTransferChildren(Fqn parentFqn, int offset, Iterator<NodeData> nodeDataIterator)
          throws IOException, ClassNotFoundException
    {
-      int parent_level = parent.getFqn().size();
-      int target_level = parent_level + 1;
+      int parentLevel = parentFqn.size();
+      int targetLevel = parentLevel + 1;
       Fqn fqn;
       int size;
       NodeData nd = nodeDataIterator.hasNext() ? nodeDataIterator.next() : null;
@@ -255,35 +270,28 @@
          // change the Fqn to fit under it
          if (offset > 0)
          {
-            fqn = Fqn.fromRelativeFqn(parent.getFqn().getAncestor(offset), fqn);
+            fqn = Fqn.fromRelativeFqn(parentFqn.getAncestor(offset), fqn);
          }
          size = fqn.size();
-         if (size <= parent_level)
+         if (size <= parentLevel)
          {
             return nd;
          }
-         else if (size > target_level)
+         else if (size > targetLevel)
          {
-            throw new IllegalStateException("NodeData " + fqn + " is not a direct child of " + parent.getFqn());
+            throw new IllegalStateException("NodeData " + fqn + " is not a direct child of " + parentFqn);
          }
 
          Map attrs = nd.getAttributes();
 
-         InternalNode internalTarget = factory.createInternalNode(fqn);
-         internalTarget.setInternalState(attrs);
-         parent.addChild(internalTarget);
+         prepareContextOptions();
+         cache.clearData(fqn);
+         prepareContextOptions();
+         cache.put(fqn, attrs);
 
-         // JBCACHE-913
-         Region region = cache.getRegion(fqn, false);
-         if (region != null && region.getEvictionPolicy() != null)
-         {
-            region.putNodeEvent(new EvictedEventNode(fqn, NodeEventType.ADD_NODE_EVENT,
-                  attrs == null ? 0 : attrs.size()));
-         }
-
          // Recursively call, which will walk down the tree
          // and return the next NodeData that's a child of our parent
-         nd = integrateStateTransferChildren(internalTarget, offset, nodeDataIterator);
+         nd = integrateStateTransferChildren(fqn, offset, nodeDataIterator);
       }
       if (nd != null && nd.isExceptionMarker())
       {
@@ -294,18 +302,18 @@
       return null;
    }
 
-   private Set<InternalNode> retainInternalNodes(InternalNode target)
+   private Set<Fqn> retainInternalNodes(Fqn target)
    {
-      Set<InternalNode> result = new HashSet<InternalNode>();
-      Fqn targetFqn = target.getFqn();
+      Set<Fqn> result = new HashSet<Fqn>();
       for (Fqn internalFqn : internalFqns)
       {
-         if (internalFqn.isChildOf(targetFqn))
+         if (internalFqn.isChildOf(target))
          {
-            InternalNode internalNode = getInternalNode(target, internalFqn);
-            if (internalNode != null)
+            prepareContextOptions();
+            Node node = getInternalNode(cache.getNode(target), internalFqn);
+            if (node != null)
             {
-               result.add(internalNode);
+               result.add(node.getFqn());
             }
          }
       }
@@ -313,10 +321,12 @@
       return result;
    }
 
-   private InternalNode getInternalNode(InternalNode parent, Fqn internalFqn)
+   private Node getInternalNode(Node parentNode, Fqn internalFqn)
    {
-      Object name = internalFqn.get(parent.getFqn().size());
-      InternalNode result = parent.getChild(name);
+      Fqn parentFqn = parentNode.getFqn();
+      Object name = internalFqn.get(parentFqn.size());
+      prepareContextOptions();
+      Node result = parentNode.getChild(name);
       if (result != null)
       {
          if (internalFqn.size() < result.getFqn().size())
@@ -328,29 +338,33 @@
       return result;
    }
 
-   private void integrateRetainedNodes(InternalNode target)
+   private void integrateRetainedNodes(Fqn target)
    {
-      Set<InternalNode> retainedNodes = retainInternalNodes(target);
-      Fqn rootFqn = target.getFqn();
-      for (InternalNode retained : retainedNodes)
+      Set<Fqn> retainedNodes = retainInternalNodes(target);
+      for (Fqn retained : retainedNodes)
       {
-         if (retained.getFqn().isChildOf(rootFqn))
+         if (retained.isChildOf(target))
          {
             integrateRetainedNode(target, retained);
          }
       }
    }
 
-   private void integrateRetainedNode(InternalNode ancestor, InternalNode descendant)
+
+   // TODO: What is this rubbish?!??
+   private void integrateRetainedNode(Fqn ancFqn, Fqn descFqn)
    {
-      Fqn descFqn = descendant.getFqn();
-      Fqn ancFqn = ancestor.getFqn();
+      prepareContextOptions();
+      InternalNode ancestor = cache.getNode(ancFqn).getDelegationTarget();
       Object name = descFqn.get(ancFqn.size());
       InternalNode child = ancestor.getChild(name);
       if (ancFqn.size() == descFqn.size() + 1)
       {
          if (child == null)
          {
+            prepareContextOptions();
+            InternalNode descendant = cache.getNode(descFqn).getDelegationTarget();
+            prepareContextOptions();
             ancestor.addChild(name, descendant);
          }
          else
@@ -373,7 +387,7 @@
          }
 
          // Keep walking down the tree
-         integrateRetainedNode(child, descendant);
+         integrateRetainedNode(child.getFqn(), descFqn);
       }
    }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/statetransfer/LegacyStateTransferIntegrator.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/statetransfer/LegacyStateTransferIntegrator.java	2008-08-06 00:56:02 UTC (rev 6523)
+++ core/trunk/src/main/java/org/jboss/cache/statetransfer/LegacyStateTransferIntegrator.java	2008-08-06 00:57:16 UTC (rev 6524)
@@ -16,6 +16,7 @@
 import org.jboss.cache.NodeSPI;
 import org.jboss.cache.Region;
 import org.jboss.cache.buddyreplication.BuddyManager;
+import org.jboss.cache.config.Configuration;
 import org.jboss.cache.eviction.EvictedEventNode;
 import org.jboss.cache.eviction.NodeEventType;
 import org.jboss.cache.factories.annotations.Inject;
@@ -43,24 +44,26 @@
 
    private static final Log log = LogFactory.getLog(LegacyStateTransferIntegrator.class);
    private static final boolean trace = log.isTraceEnabled();
-
    private CacheSPI cache;
-
    private NodeFactory factory;
-
    private Set<Fqn> internalFqns;
+   private Configuration cfg;
+   private boolean usePut;    // for JBCACHE-131
 
    @Inject
-   public void inject(CacheSPI<?, ?> cache, NodeFactory nodefactory)
+   public void inject(CacheSPI<?, ?> cache, NodeFactory nodefactory, Configuration cfg)
    {
       this.cache = cache;
       this.factory = nodefactory;
+      this.cfg = cfg;
    }
 
    @Start(priority = 14)
    public void start()
    {
       this.internalFqns = cache.getInternalFqns();
+      usePut = cfg.getCacheLoaderConfig() != null && !cfg.getCacheLoaderConfig().isFetchPersistentState() &&
+            !cfg.getCacheLoaderConfig().isShared();
    }
 
    public void integrateState(ObjectInputStream ois, Object target, Fqn targetFqn, boolean integratePersistentState) throws Exception
@@ -212,9 +215,20 @@
             if (nd != null && !nd.isMarker())
             {
                Map attributes = nd.getAttributes();
+               if (usePut)
+               {
+                  cache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
+                  cache.getInvocationContext().getOptionOverrides().setSkipCacheStatusCheck(true);
+                  target.clearData();
+                  cache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
+                  cache.getInvocationContext().getOptionOverrides().setSkipCacheStatusCheck(true);
+                  target.putAll(attributes);
+               }
+               else
+               {
+                  target.setInternalState(attributes);
+               }
 
-               target.setInternalState(attributes);
-
                // Check whether this is an integration into the buddy backup
                // subtree
                Fqn tferFqn = nd.getFqn();
@@ -276,16 +290,29 @@
 
          // We handle this NodeData.  Create a TreeNode and
          // integrate its data
-         NodeSPI target = factory.createNode(fqn, parent, attrs);
-         parent.addChild(fqn.getLastElement(), target);
-
-         // JBCACHE-913
-         Region region = cache.getRegion(fqn, false);
-         if (region != null && region.getEvictionPolicy() != null)
+         NodeSPI target;
+         if (usePut)
          {
-            region.putNodeEvent(new EvictedEventNode(fqn, NodeEventType.ADD_NODE_EVENT,
-                  attrs == null ? 0 : attrs.size()));
+            cache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
+            cache.getInvocationContext().getOptionOverrides().setSkipCacheStatusCheck(true);
+            cache.clearData(fqn);
+            cache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
+            cache.getInvocationContext().getOptionOverrides().setSkipCacheStatusCheck(true);
+            cache.put(fqn, attrs);
+            target = cache.getNode(fqn);
          }
+         else
+         {
+            target = factory.createNode(fqn, parent, attrs);
+            parent.addChild(fqn.getLastElement(), target);
+            // JBCACHE-913
+            Region region = cache.getRegion(fqn, false);
+            if (region != null && region.getEvictionPolicy() != null)
+            {
+               region.putNodeEvent(new EvictedEventNode(fqn, NodeEventType.ADD_NODE_EVENT,
+                     attrs == null ? 0 : attrs.size()));
+            }
+         }
 
          // Recursively call, which will walk down the tree
          // and return the next NodeData that's a child of our parent

Modified: core/trunk/src/main/java/org/jboss/cache/statetransfer/LegacyStateTransferManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/statetransfer/LegacyStateTransferManager.java	2008-08-06 00:56:02 UTC (rev 6523)
+++ core/trunk/src/main/java/org/jboss/cache/statetransfer/LegacyStateTransferManager.java	2008-08-06 00:57:16 UTC (rev 6524)
@@ -5,6 +5,7 @@
 import org.jboss.cache.NodeSPI;
 import org.jboss.cache.RegionEmptyException;
 import org.jboss.cache.factories.annotations.Inject;
+import org.jboss.cache.factories.annotations.Start;
 import org.jboss.cache.lock.LockManager;
 import static org.jboss.cache.lock.LockType.READ;
 import org.jboss.cache.lock.TimeoutException;
@@ -23,6 +24,7 @@
 public class LegacyStateTransferManager extends DefaultStateTransferManager
 {
    protected LockManager lockManager;
+   private boolean usePut;  // for JBCACHE-131
 
    @Inject
    public void injectLockManager(LockManager lockManager)
@@ -30,6 +32,13 @@
       this.lockManager = lockManager;
    }
 
+   @Start(priority = 14)
+   public void checkLoaders()
+   {
+      usePut = configuration.getCacheLoaderConfig() != null && !configuration.getCacheLoaderConfig().isFetchPersistentState() &&
+            !configuration.getCacheLoaderConfig().isShared();
+   }
+
    @Override
    public void getState(ObjectOutputStream out, Fqn fqn, long timeout, boolean force, boolean suppressErrors) throws Exception
    {
@@ -136,6 +145,7 @@
 
    protected void acquireLocksForStateTransfer(NodeSPI root, long timeout, boolean force) throws InterruptedException
    {
+      if (usePut) return;
       try
       {
          lockManager.lockAll(root, READ, getLockOwner(), timeout, true);
@@ -157,6 +167,7 @@
 
    protected void releaseStateTransferLocks(NodeSPI root)
    {
+      if (usePut) return;
       try
       {
          lockManager.unlockAll(root, getLockOwner());

Added: core/trunk/src/test/java/org/jboss/cache/api/mvcc/PersistingTransientStateTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/api/mvcc/PersistingTransientStateTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/api/mvcc/PersistingTransientStateTest.java	2008-08-06 00:57:16 UTC (rev 6524)
@@ -0,0 +1,13 @@
+package org.jboss.cache.api.mvcc;
+
+import org.jboss.cache.config.Configuration.NodeLockingScheme;
+import org.testng.annotations.Test;
+
+ at Test(groups = "functional")
+public class PersistingTransientStateTest extends org.jboss.cache.statetransfer.PersistingTransientStateTest
+{
+   public PersistingTransientStateTest()
+   {
+      nls = NodeLockingScheme.MVCC;
+   }
+}
\ No newline at end of file

Added: core/trunk/src/test/java/org/jboss/cache/optimistic/PersistingTransientStateTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/optimistic/PersistingTransientStateTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/optimistic/PersistingTransientStateTest.java	2008-08-06 00:57:16 UTC (rev 6524)
@@ -0,0 +1,13 @@
+package org.jboss.cache.optimistic;
+
+import org.jboss.cache.config.Configuration.NodeLockingScheme;
+import org.testng.annotations.Test;
+
+ at Test(groups = "functional")
+public class PersistingTransientStateTest extends org.jboss.cache.statetransfer.PersistingTransientStateTest
+{
+   public PersistingTransientStateTest()
+   {
+      nls = NodeLockingScheme.OPTIMISTIC;
+   }
+}

Added: core/trunk/src/test/java/org/jboss/cache/statetransfer/PersistingTransientStateTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/statetransfer/PersistingTransientStateTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/statetransfer/PersistingTransientStateTest.java	2008-08-06 00:57:16 UTC (rev 6524)
@@ -0,0 +1,113 @@
+package org.jboss.cache.statetransfer;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheFactory;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.config.CacheLoaderConfig;
+import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.Configuration.CacheMode;
+import org.jboss.cache.config.Configuration.NodeLockingScheme;
+import org.jboss.cache.loader.CacheLoader;
+import org.jboss.cache.loader.DummyInMemoryCacheLoader;
+import org.jboss.cache.transaction.DummyTransactionManagerLookup;
+import org.jboss.cache.util.TestingUtil;
+import org.testng.annotations.Test;
+
+/**
+ * Transient state SHOULD be persisted on the receiving cache IF fetchPersistentState is FALSE and the cache loader
+ * is NOT shared.
+ * <p/>
+ * Needs to be tested with PL, OL and MVCC.
+ * <p/>
+ * Pertains to JBCACHE-131
+ * <p/>
+ */
+ at Test(groups = "functional")
+public class PersistingTransientStateTest
+{
+   protected NodeLockingScheme nls = NodeLockingScheme.PESSIMISTIC;
+   protected Fqn fqn = Fqn.fromString("/a/b/c");
+   protected String k = "k", v = "v";
+
+   public void testPersistentStateTransfer() throws Exception
+   {
+      Cache<String, String> c1 = null, c2 = null;
+      try
+      {
+         CacheFactory<String, String> cf = new DefaultCacheFactory<String, String>();
+         Configuration cfg = new Configuration();
+         cfg.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+         cfg.setCacheMode(CacheMode.REPL_SYNC);
+         cfg.setFetchInMemoryState(true);
+         // configure with CL
+         IndividualCacheLoaderConfig iclc = new IndividualCacheLoaderConfig();
+         iclc.setClassName(DummyInMemoryCacheLoader.class.getName());
+         iclc.setFetchPersistentState(false);
+         CacheLoaderConfig clc = new CacheLoaderConfig();
+         clc.addIndividualCacheLoaderConfig(iclc);
+
+         cfg.setCacheLoaderConfig(clc);
+         cfg.setNodeLockingScheme(nls);
+
+         c1 = cf.createCache(cfg.clone());
+         c1.put(fqn, k, v);
+
+         assert c1.get(fqn, k).equals(v);
+         assert getLoader(c1).get(fqn).get(k).equals(v);
+
+         c2 = cf.createCache(cfg.clone());
+         assert c2.get(fqn, k).equals(v);
+         assert getLoader(c2).get(fqn).get(k).equals(v);
+      }
+      finally
+      {
+         TestingUtil.killCaches(c1, c2);
+      }
+   }
+
+   public void testPersistentStateTransferShared() throws Exception
+   {
+      Cache<String, String> c1 = null, c2 = null;
+      try
+      {
+         CacheFactory<String, String> cf = new DefaultCacheFactory<String, String>();
+         Configuration cfg = new Configuration();
+         cfg.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+         cfg.setCacheMode(CacheMode.REPL_SYNC);
+         cfg.setFetchInMemoryState(true);
+         // configure with CL
+         IndividualCacheLoaderConfig iclc = new IndividualCacheLoaderConfig();
+         iclc.setClassName(DummyInMemoryCacheLoader.class.getName());
+         iclc.setFetchPersistentState(false);
+         CacheLoaderConfig clc = new CacheLoaderConfig();
+         clc.addIndividualCacheLoaderConfig(iclc);
+         clc.setShared(true); // even though it isn't really a shared CL
+
+         cfg.setCacheLoaderConfig(clc);
+         cfg.setNodeLockingScheme(nls);
+
+         c1 = cf.createCache(cfg.clone());
+         c1.put(fqn, k, v);
+
+         assert c1.get(fqn, k).equals(v);
+         assert getLoader(c1).get(fqn).get(k).equals(v);
+
+         c2 = cf.createCache(cfg.clone());
+         assert c2.get(fqn, k).equals(v);
+         assert getLoader(c2).get(fqn) == null;
+      }
+      finally
+      {
+         TestingUtil.killCaches(c1, c2);
+      }
+   }
+
+   protected CacheLoader getLoader(Cache<?, ?> c)
+   {
+      return ((CacheSPI) c).getCacheLoaderManager().getCacheLoader();
+   }
+
+}




More information about the jbosscache-commits mailing list