[jbosscache-commits] JBoss Cache SVN: r4620 - in core/branches/1.4.X: src/org/jboss/cache/buddyreplication and 5 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Mon Oct 15 10:00:00 EDT 2007


Author: manik.surtani at jboss.com
Date: 2007-10-15 10:00:00 -0400 (Mon, 15 Oct 2007)
New Revision: 4620

Modified:
   core/branches/1.4.X/src/org/jboss/cache/InvocationContext.java
   core/branches/1.4.X/src/org/jboss/cache/TreeCache.java
   core/branches/1.4.X/src/org/jboss/cache/buddyreplication/BuddyManager.java
   core/branches/1.4.X/src/org/jboss/cache/config/Option.java
   core/branches/1.4.X/src/org/jboss/cache/interceptors/DataGravitatorInterceptor.java
   core/branches/1.4.X/tests/functional/org/jboss/cache/buddyreplication/BuddyReplicationWithCacheLoaderTest.java
   core/branches/1.4.X/tests/functional/org/jboss/cache/loader/CacheLoaderTestsBase.java
   core/branches/1.4.X/tests/functional/org/jboss/cache/misc/TestingUtil.java
Log:
JBCACHE-1192 :  Cannot gravitate data only stored in cache loader

Modified: core/branches/1.4.X/src/org/jboss/cache/InvocationContext.java
===================================================================
--- core/branches/1.4.X/src/org/jboss/cache/InvocationContext.java	2007-10-15 13:55:29 UTC (rev 4619)
+++ core/branches/1.4.X/src/org/jboss/cache/InvocationContext.java	2007-10-15 14:00:00 UTC (rev 4620)
@@ -73,7 +73,8 @@
      */
     public Option getOptionOverrides()
     {
-        return optionOverrides;
+       if (optionOverrides == null) optionOverrides = new Option();
+       return optionOverrides;
     }
 
     /**

Modified: core/branches/1.4.X/src/org/jboss/cache/TreeCache.java
===================================================================
--- core/branches/1.4.X/src/org/jboss/cache/TreeCache.java	2007-10-15 13:55:29 UTC (rev 4619)
+++ core/branches/1.4.X/src/org/jboss/cache/TreeCache.java	2007-10-15 14:00:00 UTC (rev 4620)
@@ -5284,14 +5284,19 @@
    public List _gravitateData(Fqn fqn, boolean searchSubtrees, boolean marshal)
            throws CacheException
    {
+      InvocationContext ctx = getInvocationContext();
       try
-      {
-         getInvocationContext().setOriginLocal(false);
+      {         
+         ctx.setOriginLocal(false);
          // we need to get the state for this Fqn and it's sub-nodes.
 
          // for now, perform a very simple series of getData calls.
+         // use a get() call into the cache to make sure cache loading takes place.
+         // no need to cache the original skipDataGravitation setting here - it will always be false of we got here!!
+         ctx.getOptionOverrides().setSkipDataGravitation(true);
+         DataNode actualNode = get(fqn);
+         ctx.getOptionOverrides().setSkipDataGravitation(false);
 
-         DataNode actualNode = findNode(fqn);
          Fqn backupNodeFqn = null;
          if (actualNode == null && searchSubtrees)
          {
@@ -5305,7 +5310,9 @@
                   while (childNames.hasNext() && actualNode == null)
                   {
                      backupNodeFqn = BuddyManager.getBackupFqn(childNames.next().toString(), fqn);
-                     actualNode = findNode(backupNodeFqn);
+                     ctx.getOptionOverrides().setSkipDataGravitation(true);
+                     actualNode = get(backupNodeFqn);
+                     ctx.getOptionOverrides().setSkipDataGravitation(false);
                   }
                }
             }
@@ -5320,6 +5327,8 @@
          }
          else
          {
+            // make sure we LOAD data for this node!!
+            //getData(actualNode.getFqn());
             retval = new ArrayList(3);
             retval.add(Boolean.TRUE);
 
@@ -5354,7 +5363,7 @@
       }
       finally
       {
-         getInvocationContext().setOriginLocal(true);
+         ctx.setOriginLocal(true);
       }
    }
 

Modified: core/branches/1.4.X/src/org/jboss/cache/buddyreplication/BuddyManager.java
===================================================================
--- core/branches/1.4.X/src/org/jboss/cache/buddyreplication/BuddyManager.java	2007-10-15 13:55:29 UTC (rev 4619)
+++ core/branches/1.4.X/src/org/jboss/cache/buddyreplication/BuddyManager.java	2007-10-15 14:00:00 UTC (rev 4620)
@@ -23,6 +23,7 @@
 import org.jboss.cache.marshall.RegionManager;
 import org.jboss.cache.marshall.VersionAwareMarshaller;
 import org.jboss.cache.xml.XmlHelper;
+import org.jgroups.Address;
 import org.jgroups.View;
 import org.jgroups.blocks.MethodCall;
 import org.jgroups.stack.IpAddress;
@@ -213,9 +214,9 @@
    public void init(TreeCache cache) throws Exception
    {
       this.cache = cache;
-      final Object localAddress = cache.getLocalAddress();
+      final IpAddress localAddress = (IpAddress) cache.getLocalAddress();
       buddyGroup = new BuddyGroup();
-      buddyGroup.setDataOwner((IpAddress) localAddress);
+      buddyGroup.setDataOwner(localAddress);
       buddyGroup.setGroupName(getGroupNameFromAddress(localAddress));
       log.debug("Starting buddy manager for data owner " + buddyGroup.getDataOwner());
 
@@ -477,8 +478,13 @@
 
    // -------------- static util methods ------------------
 
-   public static Fqn getBackupFqn(Object buddyGroupName, Fqn origFqn)
+   public static Fqn getBackupFqn(Object dataOwnerAddress, Fqn origFqn)
    {
+      return getBackupFqn(getGroupNameFromAddress(dataOwnerAddress), origFqn);
+   }
+
+   public static Fqn getBackupFqn(String buddyGroupName, Fqn origFqn)
+   {
       if (isBackupFqn(origFqn)) throw new RuntimeException("Cannot make a backup Fqn from a backup Fqn! Attempting to create a backup of " + origFqn);
       List elements = new ArrayList();
       elements.add(BUDDY_BACKUP_SUBTREE);

Modified: core/branches/1.4.X/src/org/jboss/cache/config/Option.java
===================================================================
--- core/branches/1.4.X/src/org/jboss/cache/config/Option.java	2007-10-15 13:55:29 UTC (rev 4619)
+++ core/branches/1.4.X/src/org/jboss/cache/config/Option.java	2007-10-15 14:00:00 UTC (rev 4620)
@@ -21,7 +21,9 @@
     private DataVersion dataVersion;
     private boolean suppressLocking;    
     private boolean forceDataGravitation;
+    private boolean skipDataGravitation;
 
+
     /**
      *
      * @since 1.4.0
@@ -116,7 +118,28 @@
       this.forceDataGravitation = enableDataGravitation;
    }
 
+   /**
+    * @return true if skipDataGravitation is set to true.
+    * @since 1.4.1.SP6
+    */
+   public boolean isSkipDataGravitation()
+   {
+      return skipDataGravitation;
+   }
 
+   /**
+    * Suppresses data gravitation when buddy replication is used.  If true, overrides {@link #setForceDataGravitation(boolean)}
+    * being set to true.  Typically used to suppress gravitation calls when {@link org.jboss.cache.config.BuddyReplicationConfig#setAutoDataGravitation(boolean)}
+    * is set to true.
+    *
+    * @param skipDataGravitation
+    * @since 1.4.1.SP6
+    */
+   public void setSkipDataGravitation(boolean skipDataGravitation)
+   {
+      this.skipDataGravitation = skipDataGravitation;
+   }
+
    public String toString()
    {
        return "Option{" +
@@ -125,6 +148,7 @@
                ", dataVersion=" + dataVersion +
                ", suppressLocking=" + suppressLocking +
                ", forceDataGravitation=" + forceDataGravitation +
+               ", skipDataGravitation=" + skipDataGravitation +
                '}';
    }
     

Modified: core/branches/1.4.X/src/org/jboss/cache/interceptors/DataGravitatorInterceptor.java
===================================================================
--- core/branches/1.4.X/src/org/jboss/cache/interceptors/DataGravitatorInterceptor.java	2007-10-15 13:55:29 UTC (rev 4619)
+++ core/branches/1.4.X/src/org/jboss/cache/interceptors/DataGravitatorInterceptor.java	2007-10-15 14:00:00 UTC (rev 4620)
@@ -63,17 +63,19 @@
    public Object invoke(MethodCall call) throws Throwable
    {
       JBCMethodCall m = (JBCMethodCall) call;
-//        if (isGravitationEnabled(getInvocationContext()))
-//        {
-//            Option opt = getInvocationContext().getOptionOverrides();
-//            if (opt == null || !opt.isSuppressDataGravitation())
-//            {
+      InvocationContext ctx = getInvocationContext();
+
+      if (((ctx.getOptionOverrides() != null) && ctx.getOptionOverrides().isSkipDataGravitation()))
+      {
+         return super.invoke(call);
+      }
+
       if (log.isTraceEnabled()) log.trace("Invoked with method call " + m);
 
       // Transactional lifecycle methods should be handled regardless of whether data gravitation is enabled or not.
       if (!isTransactionLifecycleMethod(m))
       {
-         if (isGravitationEnabled(getInvocationContext()) && MethodDeclarations.isGetMethod(m.getMethodId()))
+         if (isGravitationEnabled(ctx) && MethodDeclarations.isGetMethod(m.getMethodId()))
          {
             // test that the Fqn being requested exists locally in the cache.
             Fqn fqn = extractFqn(m.getMethodId(), m.getArgs());
@@ -86,16 +88,12 @@
             {
                if (!cache.exists(fqn))
                {
-                  BackupData data = null;
-
                   // perform a data gravitation
-                  if (localBackupExists(fqn))
+                  log.trace("Gravitating from local backup tree");
+                  BackupData data = localBackupGet(fqn);
+                  
+                  if (data == null)
                   {
-                     log.trace("Gravitating from local backup tree");
-                     data = localBackupGet(fqn);
-                  }
-                  else
-                  {
                      log.trace("Gravitating from remote backup tree");
                      // gravitate remotely.
                      data = remoteBackupGet(fqn);
@@ -135,20 +133,20 @@
                case MethodDeclarations.prepareMethod_id:
                case MethodDeclarations.optimisticPrepareMethod_id:
                   Object o = super.invoke(m);
-                  doPrepare(getInvocationContext().getGlobalTransaction());
+                  doPrepare(ctx.getGlobalTransaction());
                   return o;
                case MethodDeclarations.rollbackMethod_id:
-                  transactionMods.remove(getInvocationContext().getGlobalTransaction());
+                  transactionMods.remove(ctx.getGlobalTransaction());
                   return super.invoke(m);
                case MethodDeclarations.commitMethod_id:
-                  doCommit(getInvocationContext().getGlobalTransaction());
-                  transactionMods.remove(getInvocationContext().getGlobalTransaction());
+                  doCommit(ctx.getGlobalTransaction());
+                  transactionMods.remove(ctx.getGlobalTransaction());
                   return super.invoke(m);
             }
          }
          catch (Throwable throwable)
          {
-            transactionMods.remove(getInvocationContext().getGlobalTransaction());
+            transactionMods.remove(ctx.getGlobalTransaction());
             throw throwable;
          }
       }

Modified: core/branches/1.4.X/tests/functional/org/jboss/cache/buddyreplication/BuddyReplicationWithCacheLoaderTest.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/buddyreplication/BuddyReplicationWithCacheLoaderTest.java	2007-10-15 13:55:29 UTC (rev 4619)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/buddyreplication/BuddyReplicationWithCacheLoaderTest.java	2007-10-15 14:00:00 UTC (rev 4620)
@@ -9,9 +9,13 @@
 import org.jboss.cache.Fqn;
 import org.jboss.cache.TreeCache;
 import org.jboss.cache.config.Option;
+import org.jboss.cache.eviction.LRUPolicy;
 import org.jboss.cache.loader.CacheLoader;
 import org.jboss.cache.misc.TestingUtil;
+import org.jboss.cache.xml.XmlHelper;
 
+import java.io.File;
+
 /**
  * Tests use of the data gravitator alongside other cache loaders as well as data gravitator options such as removeOnFind.
  *
@@ -229,4 +233,142 @@
         }
     }
 
+   /**
+    * Tests whether nodes that have been evicted can successfully be
+    * gravitated.
+    *
+    * @throws Exception
+    */
+   public void testLocalGravitationOfEvictedNodes() throws Exception
+   {
+      TreeCache[] caches = null;
+      String tmpLocation = System.getProperty("java.io.tmpdir", "/tmp");
+      tmpLocation = tmpLocation + File.separator + "JBossCacheBRWithCacheLoaderTest";
+
+      try
+      {
+         TreeCache cache1 = createCacheWithCacheLoader(tmpLocation + File.separator + "1", true, true, passivation, true, false);
+         configureEviction(cache1);
+         TreeCache cache0 = createCacheWithCacheLoader(tmpLocation + File.separator + "2", true, true, passivation, true, false);
+         configureEviction(cache0);
+
+         caches = new TreeCache[2];
+         caches[0] = cache0;
+         caches[1] = cache1;
+
+         cache0.start();
+         cache1.start();
+
+         TestingUtil.blockUntilViewsReceived(caches, VIEW_BLOCK_TIMEOUT * caches.length);
+         TestingUtil.sleepThread(getSleepTimeout());
+
+
+         Fqn foo = Fqn.fromString("/foo");         
+         Fqn backupFoo = BuddyManager.getBackupFqn(cache0.getLocalAddress(), foo);
+         cache0.put(foo, "key", "value");
+
+         assertTrue("Data should exist in data owner", cache0.exists(foo));
+         assertTrue("Buddy should have data", cache1.exists(backupFoo));
+
+         // Sleep long enough for eviction to run twice plus a bit
+         TestingUtil.sleepThread(3050);
+
+         // test that the data we're looking for has been evicted in both the data owner and the buddy.
+         assertFalse("Data should have evicted in data owner", cache0.exists(foo));
+         assertFalse("Buddy should have data evicted", cache1.exists(backupFoo));
+
+         // now test that this exists in both loaders.
+         assertNotNull("Should exist in data owner's cache loader", cache0.getCacheLoader().get(foo));
+         assertNotNull("Should exist in buddy's loader", cache1.getCacheLoader().get(backupFoo));
+
+         // a local gravitation should occur since cache1 has foo in it's backup tree.
+         assertEquals("Passivated value available from buddy", "value", cache1.get(foo, "key"));
+      }
+      finally
+      {
+         cleanup(caches);
+         TestingUtil.recursiveRemove(new File(tmpLocation));
+      }
+   }
+
+   /**
+    * Tests whether nodes that have been evicted can successfully be
+    * gravitated.
+    *
+    * @throws Exception
+    */
+   public void testRemoteGravitationOfEvictedNodes() throws Exception
+   {
+      TreeCache[] caches = null;
+      String tmpLocation = System.getProperty("java.io.tmpdir", "/tmp");
+      tmpLocation = tmpLocation + File.separator + "JBossCacheBRWithCacheLoaderTest";
+
+      try
+      {
+         TreeCache cache0 = createCacheWithCacheLoader(tmpLocation + File.separator + "0", true, true, passivation, true, false);
+         configureEviction(cache0);
+         TreeCache cache1 = createCacheWithCacheLoader(tmpLocation + File.separator + "1", true, true, passivation, true, false);
+         configureEviction(cache1);
+         TreeCache cache2 = createCacheWithCacheLoader(tmpLocation + File.separator + "2", true, true, passivation, true, false);
+         configureEviction(cache2);
+
+         caches = new TreeCache[3];
+         caches[0] = cache0;
+         caches[1] = cache1;
+         caches[2] = cache2;
+
+         cache0.start();
+         cache1.start();
+         cache2.start();
+
+         TestingUtil.blockUntilViewsReceived(caches, 600000);
+         TestingUtil.sleepThread(getSleepTimeout());
+
+
+         assertTrue("Cache1 should be cache0's buddy!", cache0.getBuddyManager().getBuddyAddresses().contains(cache1.getLocalAddress()));
+
+         Fqn foo = Fqn.fromString("/foo");
+         Fqn backupFoo = BuddyManager.getBackupFqn(cache0.getLocalAddress(), foo);
+         cache0.put(foo, "key", "value");
+
+         // test that the data exists in both the data owner and the buddy
+         assertTrue("Data should exist in data owner", cache0.exists(foo));
+         assertTrue("Buddy should have data", cache1.exists(backupFoo));
+
+         // Sleep long enough for eviction to run twice plus a bit
+         TestingUtil.sleepThread(3050);
+
+         // test that the data we're looking for has been evicted in both the data owner and the buddy.
+         assertFalse("Data should have evicted in data owner", cache0.exists(foo));
+         assertFalse("Buddy should have data evicted", cache1.exists(backupFoo));
+
+         // now test that this exists in both loaders.
+         assertNotNull("Should exist in data owner's loader", cache0.getCacheLoader().get(foo));
+         assertNotNull("Should exist in buddy's loader", cache1.getCacheLoader().get(backupFoo));
+
+         // doing a get on cache2 will guarantee a remote data gravitation.
+         assertEquals("Passivated value available from buddy", "value", cache2.get(foo, "key"));
+      }
+      finally
+      {
+         cleanup(caches);
+         TestingUtil.recursiveRemove(new File(tmpLocation));
+      }
+   }
+
+   private void configureEviction(TreeCache cache) throws Exception
+   {
+      String evictionConfig = "<config>\n" +
+                              "              <attribute name=\"wakeUpIntervalSeconds\">1</attribute>\n" +
+                              "              <region name=\"/_default_\">\n" +
+                              "                  <attribute name=\"maxNodes\">1</attribute>\n" +
+                              "                  <attribute name=\"timeToLiveSeconds\">1</attribute>\n" +
+                              "                  <attribute name=\"maxAgeSeconds\">2</attribute>\n" +
+                              "              </region>\n" +
+                              "           </config>";
+
+      cache.setEvictionPolicyClass(LRUPolicy.class.getName());
+      cache.setEvictionPolicyConfig(XmlHelper.stringToElement(evictionConfig));
+   }
+
 }

Modified: core/branches/1.4.X/tests/functional/org/jboss/cache/loader/CacheLoaderTestsBase.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/loader/CacheLoaderTestsBase.java	2007-10-15 13:55:29 UTC (rev 4619)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/loader/CacheLoaderTestsBase.java	2007-10-15 14:00:00 UTC (rev 4620)
@@ -73,26 +73,6 @@
       ; // returns immediately in this case.  Subclasses may override where a delay is needed.
    }
 
-    protected void clean(File dir)
-    {
-        File[] files = dir.listFiles();
-        if (files != null)
-        {
-            for (int i = 0; i < files.length; i++)
-            {
-                if (files[i].isDirectory())
-                {
-                    clean(files[i]);
-                }
-                else
-                {
-                    if (!files[i].delete()) files[i].deleteOnExit();
-                }
-            }
-        }
-    }
-
-
     public void testPrint() throws CacheException {
       final Fqn NODE=Fqn.fromString("/test");
       final String KEY="key";

Modified: core/branches/1.4.X/tests/functional/org/jboss/cache/misc/TestingUtil.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/misc/TestingUtil.java	2007-10-15 13:55:29 UTC (rev 4619)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/misc/TestingUtil.java	2007-10-15 14:00:00 UTC (rev 4620)
@@ -8,6 +8,7 @@
 package org.jboss.cache.misc;
 
 import java.util.Vector;
+import java.io.File;
 
 import org.jboss.cache.TreeCache;
 import org.jboss.cache.TreeCacheMBean;
@@ -148,4 +149,29 @@
       }
       catch (InterruptedException ie) {}
    }
+
+   public static void recursiveRemove(File dir)
+   {
+      if (dir == null) return;
+      if (!dir.isDirectory())
+      {
+         if (!dir.delete()) dir.deleteOnExit();
+         return;
+      }
+      File[] files = dir.listFiles();
+      if (files != null)
+      {
+         for (int i = 0; i < files.length; i++)
+         {
+            if (files[i].isDirectory())
+            {
+               recursiveRemove(files[i]);
+            }
+            else
+            {
+               if (!files[i].delete()) files[i].deleteOnExit();
+            }
+         }
+      }
+   }
 }




More information about the jbosscache-commits mailing list