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

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Fri Aug 20 11:45:26 EDT 2010


Author: galder.zamarreno at jboss.com
Date: 2010-08-20 11:45:26 -0400 (Fri, 20 Aug 2010)
New Revision: 8443

Added:
   core/trunk/src/test/java/org/jboss/cache/eviction/LongTransactionEvictionsTest.java
Modified:
   core/trunk/pom.xml
   core/trunk/src/main/java/org/jboss/cache/Region.java
   core/trunk/src/main/java/org/jboss/cache/RegionImpl.java
   core/trunk/src/main/java/org/jboss/cache/eviction/BaseEvictionAlgorithm.java
   core/trunk/src/main/java/org/jboss/cache/eviction/EvictedEventNode.java
   core/trunk/src/main/java/org/jboss/cache/eviction/EvictionEvent.java
   core/trunk/src/main/java/org/jboss/cache/eviction/ExpirationAlgorithm.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/statetransfer/LegacyStateTransferIntegrator.java
Log:
[JBCACHE-1582] (ExpirationAlgorithm doesn't evict nodes that have been created in a long Tx) Pass command and transactional information to the eviction algorithm in order to find out expiration time and whether the call is transactional. This allows eviction transaction expiration tree nodes to be delayed until they've been committed and resolves a memory leak.

Modified: core/trunk/pom.xml
===================================================================
--- core/trunk/pom.xml	2010-06-02 12:24:45 UTC (rev 8442)
+++ core/trunk/pom.xml	2010-08-20 15:45:26 UTC (rev 8443)
@@ -143,6 +143,12 @@
             <scope>test</scope>
             <classifier>jdk15</classifier>
         </dependency>
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging-spi</artifactId>
+            <version>2.0.5.GA</version>
+            <scope>test</scope>
+         </dependency>
     </dependencies>
 
     <build>

Modified: core/trunk/src/main/java/org/jboss/cache/Region.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/Region.java	2010-06-02 12:24:45 UTC (rev 8442)
+++ core/trunk/src/main/java/org/jboss/cache/Region.java	2010-08-20 15:45:26 UTC (rev 8443)
@@ -22,6 +22,7 @@
 package org.jboss.cache;
 
 import org.jboss.cache.annotations.Compat;
+import org.jboss.cache.commands.DataCommand;
 import org.jboss.cache.config.Configuration;
 import org.jboss.cache.config.EvictionPolicyConfig;
 import org.jboss.cache.config.EvictionRegionConfig;
@@ -29,6 +30,8 @@
 import org.jboss.cache.eviction.EvictionEvent;
 import org.jboss.cache.eviction.EvictionPolicy;
 
+import javax.transaction.Transaction;
+
 /**
  * Defines characteristics such as class loading and eviction of {@link org.jboss.cache.Node}s belonging to a Region in a {@link Cache}.
  * A Region is described by an {@link #getFqn() Fqn} relative to the root of the cache.
@@ -162,10 +165,10 @@
     * @param elementDifference passed in to the constructor of {@link org.jboss.cache.eviction.EvictionEvent}
     * @return an EvictedEventNode that has been created for this queue
     */
-   EvictionEvent registerEvictionEvent(Fqn fqn, EvictionEvent.Type eventType, int elementDifference);
+   EvictionEvent registerEvictionEvent(Fqn fqn, EvictionEvent.Type eventType, int elementDifference, DataCommand command, Transaction tx);
 
    /**
-    * An overloaded version of {@link #registerEvictionEvent(Fqn, org.jboss.cache.eviction.EvictionEvent.Type, int)} which
+    * An overloaded version of {@link #registerEvictionEvent(Fqn, org.jboss.cache.eviction.EvictionEvent.Type, int, DataCommand, Transaction)} which
     * uses a default elementDifference value.
     *
     * @param fqn       passed in to the constructor of {@link org.jboss.cache.eviction.EvictionEvent}

Modified: core/trunk/src/main/java/org/jboss/cache/RegionImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/RegionImpl.java	2010-06-02 12:24:45 UTC (rev 8442)
+++ core/trunk/src/main/java/org/jboss/cache/RegionImpl.java	2010-08-20 15:45:26 UTC (rev 8443)
@@ -24,6 +24,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.annotations.Compat;
+import org.jboss.cache.commands.DataCommand;
 import org.jboss.cache.config.Configuration;
 import org.jboss.cache.config.EvictionAlgorithmConfig;
 import org.jboss.cache.config.EvictionPolicyConfig;
@@ -31,6 +32,7 @@
 import org.jboss.cache.eviction.*;
 import org.jboss.cache.util.Util;
 
+import javax.transaction.Transaction;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.BlockingQueue;
@@ -157,12 +159,12 @@
 
    public void markNodeCurrentlyInUse(Fqn fqn, long timeout)
    {
-      registerEvictionEvent(fqn, EvictionEvent.Type.MARK_IN_USE_EVENT, 0).setInUseTimeout(timeout);
+      registerEvictionEvent(fqn, EvictionEvent.Type.MARK_IN_USE_EVENT, 0, null, null).setInUseTimeout(timeout);
    }
 
    public void unmarkNodeCurrentlyInUse(Fqn fqn)
    {
-      registerEvictionEvent(fqn, EvictionEvent.Type.UNMARK_USE_EVENT, 0);
+      registerEvictionEvent(fqn, EvictionEvent.Type.UNMARK_USE_EVENT, 0, null, null);
    }
 
    @Override
@@ -223,14 +225,14 @@
 
    public EvictionEvent registerEvictionEvent(Fqn fqn, EvictionEvent.Type eventType)
    {
-      return registerEvictionEvent(fqn, eventType, 0);
+      return registerEvictionEvent(fqn, eventType, 0, null, null);
    }
 
-   public EvictionEvent registerEvictionEvent(Fqn fqn, EvictionEvent.Type eventType, int elementDifference)
+   public EvictionEvent registerEvictionEvent(Fqn fqn, EvictionEvent.Type eventType, int elementDifference, DataCommand command, Transaction tx)
    {
       if (evictionAlgorithm.canIgnoreEvent(eventType)) return null;
 
-      EvictionEvent event = new EvictionEvent(fqn, eventType, elementDifference);
+      EvictionEvent event = new EvictionEvent(fqn, eventType, elementDifference, command, tx);
       registerEvictionEvent(event);
       return event;
    }
@@ -314,7 +316,8 @@
       clone.createQueue();
       for (EvictionEvent een : this.evictionEventQueue)
       {
-         clone.registerEvictionEvent(een.getFqn(), een.getEventType(), een.getElementDifference());
+         clone.registerEvictionEvent(een.getFqn(), een.getEventType(), een.getElementDifference(), een.getCommand(),
+                                     een.getTransaction());
       }
       return clone;
    }

Modified: core/trunk/src/main/java/org/jboss/cache/eviction/BaseEvictionAlgorithm.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/eviction/BaseEvictionAlgorithm.java	2010-06-02 12:24:45 UTC (rev 8442)
+++ core/trunk/src/main/java/org/jboss/cache/eviction/BaseEvictionAlgorithm.java	2010-08-20 15:45:26 UTC (rev 8443)
@@ -260,9 +260,10 @@
    {
       if (trace) log.trace("Attempting to evict cache node with fqn of " + fqn);
 
+      boolean evictionResult;
       try
       {
-         evictionActionPolicy.evict(fqn);
+         evictionResult = evictionActionPolicy.evict(fqn);
       }
       catch (TimeoutException e)
       {
@@ -276,12 +277,12 @@
          return false;
       }
 
-      if (trace)
+      if (evictionResult)
       {
-         log.trace("Eviction of cache node with fqn of " + fqn + " successful");
+         if (trace) log.trace("Eviction of cache node with fqn of " + fqn + " successful");
       }
 
-      return true;
+      return evictionResult;
    }
 
    protected void processMarkInUseNodes(Fqn fqn, long inUseTimeout) throws EvictionException

Modified: core/trunk/src/main/java/org/jboss/cache/eviction/EvictedEventNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/eviction/EvictedEventNode.java	2010-06-02 12:24:45 UTC (rev 8442)
+++ core/trunk/src/main/java/org/jboss/cache/eviction/EvictedEventNode.java	2010-08-20 15:45:26 UTC (rev 8443)
@@ -35,7 +35,7 @@
 {
    public EvictedEventNode(Fqn fqn, Type type, int elementDifference)
    {
-      super(fqn, type, elementDifference);
+      super(fqn, type, elementDifference, null, null);
    }
 
    public EvictedEventNode(EvictionEvent ee)

Modified: core/trunk/src/main/java/org/jboss/cache/eviction/EvictionEvent.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/eviction/EvictionEvent.java	2010-06-02 12:24:45 UTC (rev 8442)
+++ core/trunk/src/main/java/org/jboss/cache/eviction/EvictionEvent.java	2010-08-20 15:45:26 UTC (rev 8443)
@@ -22,7 +22,10 @@
 package org.jboss.cache.eviction;
 
 import org.jboss.cache.Fqn;
+import org.jboss.cache.commands.DataCommand;
 
+import javax.transaction.Transaction;
+
 /**
  * An eviction event records activity on nodes in the cache.  These are recorded on a {@link org.jboss.cache.Region} for processing
  * later by calls to {@link org.jboss.cache.Region#processEvictionQueues()}.
@@ -38,6 +41,8 @@
 
    private long inUseTimeout;
    private long creationTimestamp;
+   private DataCommand command;
+   private Transaction transaction;
 
    public EvictionEvent()
    {
@@ -54,12 +59,14 @@
       UNMARK_USE_EVENT
    }
 
-   public EvictionEvent(Fqn fqn, Type type, int elementDifference)
+   public EvictionEvent(Fqn fqn, Type type, int elementDifference, DataCommand command, Transaction tx)
    {
       this.fqn = fqn;
       this.type = type;
       this.elementDifference = elementDifference;
       this.creationTimestamp = System.currentTimeMillis();
+      this.command = command;
+      this.transaction = tx;
    }
 
    public long getCreationTimestamp()
@@ -107,6 +114,22 @@
       return type;
    }
 
+   public DataCommand getCommand() {
+      return command;
+   }
+
+   public void setCommand(DataCommand command) {
+      this.command = command;
+   }
+
+   public Transaction getTransaction() {
+      return transaction;
+   }
+
+   public void setTransaction(Transaction transaction) {
+      this.transaction = transaction;
+   }
+
    @Override
    public String toString()
    {
@@ -122,6 +145,6 @@
     */
    public EvictionEvent copy(Fqn newRoot)
    {
-      return new EvictionEvent(Fqn.fromRelativeFqn(newRoot, fqn), type, elementDifference);
+      return new EvictionEvent(Fqn.fromRelativeFqn(newRoot, fqn), type, elementDifference, command, transaction);
    }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/eviction/ExpirationAlgorithm.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/eviction/ExpirationAlgorithm.java	2010-06-02 12:24:45 UTC (rev 8442)
+++ core/trunk/src/main/java/org/jboss/cache/eviction/ExpirationAlgorithm.java	2010-08-20 15:45:26 UTC (rev 8443)
@@ -25,9 +25,15 @@
 import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.NodeSPI;
+import org.jboss.cache.commands.DataCommand;
+import org.jboss.cache.commands.write.PutDataMapCommand;
+import org.jboss.cache.commands.write.PutKeyValueCommand;
 import org.jboss.cache.config.EvictionAlgorithmConfig;
 import org.jboss.cache.eviction.EvictionEvent.Type;
 
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
 import java.util.Iterator;
 import java.util.SortedSet;
 import java.util.TreeSet;
@@ -92,15 +98,20 @@
    private void addEvictionEntry(EvictionEvent node)
    {
       Fqn fqn = node.getFqn();
-      addEvictionEntry(fqn);
+      addEvictionEntry(fqn, node.getCommand(), node.getTransaction());
    }
 
-   private void addEvictionEntry(Fqn fqn)
+   private void addEvictionEntry(Fqn fqn, DataCommand command, Transaction tx)
    {
       Long l = getExpiration(fqn);
-      if (l == null)
-         return;
+      if (l == null) {
+         if (command != null)
+            l = getExpirationFromCommand(command);
 
+         if (l == null)
+            return;
+      }
+
       if (l == -1)
       {
          if (config.isWarnNoExpirationKey() && log.isWarnEnabled())
@@ -110,13 +121,29 @@
       }
       else
       {
-         setExpiration(fqn, l);
+         setExpiration(fqn, l, tx);
       }
    }
 
-   private void setExpiration(Fqn fqn, Long l)
+   private Long getExpirationFromCommand(DataCommand command) {
+      if (command instanceof PutKeyValueCommand) {
+         PutKeyValueCommand putKeyCommand = (PutKeyValueCommand) command;
+         if (putKeyCommand.getKey().equals(config.getExpirationKeyName())) {
+            return (Long) putKeyCommand.getValue();
+         }
+      } else if (command instanceof PutDataMapCommand) {
+         PutDataMapCommand putDataCommand = (PutDataMapCommand) command;
+         Object expiration = putDataCommand.getData().get(config.getExpirationKeyName());
+         if (expiration != null) {
+            return (Long) expiration;
+         }
+      }
+      return null;
+   }
+
+   private void setExpiration(Fqn fqn, Long l, Transaction tx)
    {
-      ExpirationEntry ee = new ExpirationEntry(fqn, l);
+      ExpirationEntry ee = new ExpirationEntry(fqn, l, tx);
       if (trace)
          log.trace("adding eviction entry: " + ee);
       set.add(ee);
@@ -171,7 +198,7 @@
    private void markInUse(EvictionEvent node)
    {
       long expiration = node.getInUseTimeout() + System.currentTimeMillis();
-      setExpiration(node.getFqn(), expiration);
+      setExpiration(node.getFqn(), expiration, node.getTransaction());
    }
 
    @Override
@@ -184,8 +211,23 @@
       for (Iterator<ExpirationEntry> i = set.iterator(); i.hasNext();)
       {
          ExpirationEntry ee = i.next();
+         if (trace)
+            log.trace("attempt to prune: " + ee);
+
          Long ce = getExpiration(ee.getFqn());
-         if (ce == null || ce == -1 || ce > ee.getExpiration())
+         if (ce == null) {
+            if (ee.getTransaction() != null && isTransactionActive(ee.getTransaction())) {
+               if (trace)
+                  log.trace("transaction active, keep eviction entry: " + ee);
+               continue;
+            } else {
+               // Expiration now older
+               i.remove();
+               continue;
+            }
+         }
+
+         if (ce == -1 || ce > ee.getExpiration())
          {
             // Expiration now older
             i.remove();
@@ -207,12 +249,28 @@
                "Set expiration for nodes in this region");
    }
 
+   private boolean isTransactionActive(Transaction transaction) {
+      try {
+         switch (transaction.getStatus()) {
+            case Status.STATUS_UNKNOWN:
+            case Status.STATUS_ROLLEDBACK:
+            case Status.STATUS_COMMITTED:
+            case Status.STATUS_NO_TRANSACTION:
+               return false;
+            default:
+               return true;
+         }
+      } catch (SystemException e) {
+         return false;
+      }
+   }
+
    @Override
    public void resetEvictionQueue()
    {
       for (ExpirationEntry ee : set)
       {
-         addEvictionEntry(ee.getFqn());
+         addEvictionEntry(ee.getFqn(), null, null);
       }
    }
 
@@ -250,16 +308,19 @@
       private long expiration;
 
       private Fqn fqn;
+      
+      private Transaction transaction;
 
       public ExpirationEntry(Fqn fqn)
       {
          this.fqn = fqn;
       }
 
-      public ExpirationEntry(Fqn fqn, long expiration)
+      public ExpirationEntry(Fqn fqn, long expiration, Transaction transaction)
       {
          this.fqn = fqn;
          this.expiration = expiration;
+         this.transaction = transaction;
       }
 
       /**
@@ -291,6 +352,11 @@
          return fqn;
       }
 
+      public Transaction getTransaction()
+      {
+         return transaction;
+      }
+
       @Override
       public boolean equals(Object o)
       {

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java	2010-06-02 12:24:45 UTC (rev 8442)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java	2010-08-20 15:45:26 UTC (rev 8443)
@@ -26,6 +26,7 @@
 import org.jboss.cache.InvocationContext;
 import org.jboss.cache.Region;
 import org.jboss.cache.RegionManager;
+import org.jboss.cache.commands.DataCommand;
 import org.jboss.cache.commands.read.GetDataMapCommand;
 import org.jboss.cache.commands.read.GetKeyValueCommand;
 import org.jboss.cache.commands.read.GetNodeCommand;
@@ -41,6 +42,8 @@
 import org.jboss.cache.factories.annotations.Inject;
 import org.jboss.cache.interceptors.base.CommandInterceptor;
 
+import javax.transaction.Transaction;
+
 /**
  * Eviction Interceptor.
  * <p/>
@@ -87,7 +90,7 @@
          Region r;
          if (fqn != null && (r = getRegion(fqn)) != null)
          {
-            registerEvictionEventToRegionManager(fqn, ADD_NODE_EVENT, 0, r);
+            registerEvictionEventToRegionManager(fqn, ADD_NODE_EVENT, 0, r, null, null);
          }
       }
       return retVal;
@@ -106,7 +109,17 @@
       Region r;
       if (command.getFqn() != null && command.getKey() != null && (r = getRegion(command.getFqn())) != null)
       {
-         registerEvictionEventToRegionManager(command.getFqn(), ADD_ELEMENT_EVENT, 1, r);
+         boolean isTransactional = ctx.getTransactionContext() != null;
+         if (isTransactional)
+         {
+            registerEvictionEventToRegionManager(command.getFqn(), ADD_ELEMENT_EVENT, 1, r, command,
+                                                 ctx.getTransactionContext().getTransaction());
+         }
+         else
+         {
+            registerEvictionEventToRegionManager(command.getFqn(), ADD_ELEMENT_EVENT, 1, r, null, null);
+         }
+
       }
       return retVal;
    }
@@ -133,7 +146,16 @@
             {
                size = command.getData().size();
             }
-            registerEvictionEventToRegionManager(fqn, ADD_NODE_EVENT, size, r);
+            boolean isTransactional = ctx.getTransactionContext() != null;
+            if (isTransactional)
+            {
+               registerEvictionEventToRegionManager(fqn, ADD_NODE_EVENT, size, r, command,
+                                                    ctx.getTransactionContext().getTransaction());
+            }
+            else
+            {
+               registerEvictionEventToRegionManager(fqn, ADD_NODE_EVENT, size, r, null, null);
+            }
          }
       }
       return retVal;
@@ -157,7 +179,7 @@
          Region r;
          if (fqn != null && command.getKey() != null && (r = getRegion(fqn)) != null)
          {
-            registerEvictionEventToRegionManager(fqn, REMOVE_ELEMENT_EVENT, 1, r);
+            registerEvictionEventToRegionManager(fqn, REMOVE_ELEMENT_EVENT, 1, r, null, null);
          }
       }
       return retVal;
@@ -184,7 +206,7 @@
          Region r;
          if (fqn != null && (r = getRegion(fqn)) != null)
          {
-            registerEvictionEventToRegionManager(fqn, VISIT_NODE_EVENT, 0, r);
+            registerEvictionEventToRegionManager(fqn, VISIT_NODE_EVENT, 0, r, null, null);
          }
       }
       return retVal;
@@ -212,7 +234,7 @@
       }
       else if (fqn != null && command.getKey() != null && (r = getRegion(fqn)) != null)
       {
-         registerEvictionEventToRegionManager(fqn, VISIT_NODE_EVENT, 0, r);
+         registerEvictionEventToRegionManager(fqn, VISIT_NODE_EVENT, 0, r, null, null);
       }
       return retVal;
    }
@@ -224,7 +246,7 @@
       Region r;
       if (command.getFqn() != null && (r = getRegion(command.getFqn())) != null)
       {
-         registerEvictionEventToRegionManager(command.getFqn(), REMOVE_NODE_EVENT, 0, r);
+         registerEvictionEventToRegionManager(command.getFqn(), REMOVE_NODE_EVENT, 0, r, null, null);
       }
       return retVal;
    }
@@ -236,12 +258,13 @@
       Region r;
       if (command.getFqn() != null && (r = getRegion(command.getFqn())) != null)
       {
-         registerEvictionEventToRegionManager(command.getFqn(), REMOVE_NODE_EVENT, 0, r);
+         registerEvictionEventToRegionManager(command.getFqn(), REMOVE_NODE_EVENT, 0, r, null, null);
       }
       return retVal;
    }
 
-   private void registerEvictionEventToRegionManager(Fqn fqn, EvictionEvent.Type type, int elementDifference, Region region)
+   private void registerEvictionEventToRegionManager(Fqn fqn, EvictionEvent.Type type, int elementDifference,
+                                                     Region region, DataCommand command, Transaction tx)
    {
       //we do not trigger eviction events for resident nodes
       if (dataContainer.isResident(fqn))
@@ -249,7 +272,7 @@
          if (trace) log.trace("Ignoring Fqn " + fqn + " as it is marked as resident");
          return;
       }
-      region.registerEvictionEvent(fqn, type, elementDifference);
+      region.registerEvictionEvent(fqn, type, elementDifference, command, tx);
 
       if (trace) log.trace("Registering event " + type + " on node " + fqn);
    }

Modified: core/trunk/src/main/java/org/jboss/cache/statetransfer/LegacyStateTransferIntegrator.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/statetransfer/LegacyStateTransferIntegrator.java	2010-06-02 12:24:45 UTC (rev 8442)
+++ core/trunk/src/main/java/org/jboss/cache/statetransfer/LegacyStateTransferIntegrator.java	2010-08-20 15:45:26 UTC (rev 8443)
@@ -328,7 +328,7 @@
             Region region = cache.getRegion(fqn, false);
             if (region != null && region.getEvictionRegionConfig() != null)
             {
-               region.registerEvictionEvent(fqn, EvictionEvent.Type.ADD_NODE_EVENT, attrs == null ? 0 : attrs.size());
+               region.registerEvictionEvent(fqn, EvictionEvent.Type.ADD_NODE_EVENT, attrs == null ? 0 : attrs.size(), null, null);
             }
          }
 
@@ -423,4 +423,4 @@
          integrateRetainedNode(child, descendant);
       }
    }
-}
\ No newline at end of file
+}

Added: core/trunk/src/test/java/org/jboss/cache/eviction/LongTransactionEvictionsTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/eviction/LongTransactionEvictionsTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/eviction/LongTransactionEvictionsTest.java	2010-08-20 15:45:26 UTC (rev 8443)
@@ -0,0 +1,153 @@
+package org.jboss.cache.eviction;
+
+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.EvictionConfig;
+import org.jboss.cache.config.EvictionRegionConfig;
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+import static org.testng.AssertJUnit.*;
+
+ at Test(groups = {"functional"}, testName = "LongTransactionEvictionsTest")
+public class LongTransactionEvictionsTest
+{
+   public void testFIFOAlgoWithLongTx() throws Exception
+   {
+      // Create the cache
+      CacheFactory<String, Object> factory = new DefaultCacheFactory<String, Object>();
+      final Cache<String, Object> cache = factory.createCache(false);
+
+      // Configure the Eviction
+      EvictionConfig evictionConfig = new EvictionConfig();
+      cache.getConfiguration().setEvictionConfig(evictionConfig);
+
+      // Set the LRUAlgorithm as eviction algorithm
+      int maxNodes = 1;
+      long timeout = 4000;
+      FIFOAlgorithmConfig fifo = new FIFOAlgorithmConfig(maxNodes);
+      fifo.setMinTimeToLive(timeout);
+      EvictionRegionConfig erConfig = new EvictionRegionConfig(Fqn.ROOT, fifo);
+      evictionConfig.setDefaultEvictionRegionConfig(erConfig);
+
+      // Set the wakeup interval
+      long wakeupInterval = 1000;
+      evictionConfig.setWakeupInterval(wakeupInterval);
+
+      cache.getConfiguration().setInvocationBatchingEnabled(true);
+
+      // Start the cache
+      cache.start();
+      cache.startBatch();
+      cache.put(Fqn.fromElements("a"), "a", "value");
+      // Add a pause before committing
+      long pause = wakeupInterval + 1000;
+      Thread.sleep(pause);
+
+      cache.endBatch(true);
+      AssertJUnit.assertEquals(1, ((CacheSPI<String, Object>)cache).getNumberOfNodes());
+      cache.startBatch();
+      cache.put(Fqn.fromElements("b"), "b", "value");
+
+      // Add a pause before committing
+      pause = wakeupInterval + 1000;
+      assertEquals(1, ((CacheSPI<String, Object>)cache).getNumberOfNodes());
+      Thread.sleep(pause);
+
+      cache.endBatch(true);
+      assertEquals(2, ((CacheSPI<String, Object>)cache).getNumberOfNodes());
+
+      Thread.sleep(timeout + pause);
+
+      // We expect to have 1 entry into the cache there
+      assertEquals(1, ((CacheSPI<String, Object>)cache).getNumberOfNodes());
+   }
+
+   public void testLRUAlgoWithLongTx() throws Exception
+   {
+      // Create the cache
+      CacheFactory<String, Object> factory = new DefaultCacheFactory<String, Object>();
+      final Cache<String, Object> cache = factory.createCache(false);
+
+      // Configure the Eviction
+      EvictionConfig evictionConfig = new EvictionConfig();
+      cache.getConfiguration().setEvictionConfig(evictionConfig);
+
+      // Set the LRUAlgorithm as eviction algorithm
+      int maxNodes = 5;
+      long timeout = 4000;
+      LRUAlgorithmConfig lru = new LRUAlgorithmConfig(1000, timeout, maxNodes);
+      EvictionRegionConfig erConfig = new EvictionRegionConfig(Fqn.ROOT, lru);
+      evictionConfig.setDefaultEvictionRegionConfig(erConfig);
+
+      // Set the wakeup interval
+      long wakeupInterval = 1000;
+      evictionConfig.setWakeupInterval(wakeupInterval);
+
+      cache.getConfiguration().setInvocationBatchingEnabled(true);
+
+      // Start the cache
+      cache.start();
+
+      cache.startBatch();
+      Fqn<String> fqn = Fqn.fromElements("key");
+      cache.put(fqn, "key", "value");
+
+      // Add a pause before committing
+      long pause = wakeupInterval + 1000;
+      Thread.sleep(pause);
+
+      cache.endBatch(true);
+
+      Thread.sleep(timeout + pause);
+
+      // We expect to have an empty cache there
+      assertEquals(0, ((CacheSPI<String, Object>)cache).getNumberOfNodes());
+   }
+
+   public void testExpAlgoWithLongTx() throws Exception
+   {
+      // Create the cache
+      CacheFactory<String, Object> factory = new DefaultCacheFactory<String, Object>();
+      final Cache<String, Object> cache = factory.createCache(false);
+
+      // Configure the Eviction
+      EvictionConfig evictionConfig = new EvictionConfig();
+      cache.getConfiguration().setEvictionConfig(evictionConfig);
+
+      // Set the ExpirationAlgorithm as eviction algorithm
+      int maxNodes = 5;
+      ExpirationAlgorithmConfig ea = new ExpirationAlgorithmConfig();
+      ea.setMaxNodes(maxNodes);
+      EvictionRegionConfig erConfig = new EvictionRegionConfig(Fqn.ROOT, ea);
+      evictionConfig.setDefaultEvictionRegionConfig(erConfig);
+
+      // Set the wakeup interval
+      long wakeupInterval = 1000;
+      evictionConfig.setWakeupInterval(wakeupInterval);
+
+      cache.getConfiguration().setInvocationBatchingEnabled(true);
+
+      // Start the cache
+      cache.start();
+
+      cache.startBatch();
+      long timeout = 4000;
+      Fqn<String> fqn = Fqn.fromElements("key");
+      Long future = new Long(System.currentTimeMillis() + timeout);
+      cache.put(fqn, ExpirationAlgorithmConfig.EXPIRATION_KEY, future);
+
+      // Add a pause before committing
+      long pause = wakeupInterval + 1000;
+      Thread.sleep(pause);
+
+      cache.endBatch(true);
+
+      Thread.sleep(timeout + pause);
+
+      // We expect to have an empty cache there
+      assertEquals(0, ((CacheSPI<String, Object>)cache).getNumberOfNodes());
+   }
+}
\ No newline at end of file



More information about the jbosscache-commits mailing list