[jbosscache-dev] CacheStores and expiration WAS: [horizon-commits] Horizon SVN: r40 - in trunk/src/test/java/org/horizon: expiry and 1 other directories.

Manik Surtani manik at jboss.org
Wed Mar 25 12:12:48 EDT 2009


Ok, I have checked in all core changes around expiry, so that you can  
now specify expiry:

	(a) programmatically (per entry) or declaratively (cache-wide), and
	(b) absolutely (lifespan), relatively (idle time), or both.

See examples, etc on:

	http://www.jboss.org/community/docs/DOC-13449

So tests pass, and the core structure works well.  The only thing is,  
folks who have implemented CacheStores (Mircea and Adrian) may want to  
revisit your implementations.  Like I said tests pass, even the ones I  
added to BaseCacheStoreTest to test all forms of expiration, but there  
are probably optimisations you can do to prevent reading and  
deserializing expired state, only to have isExpired() return true and  
have to throw it away.

Cheers
Manik


Begin forwarded message:

> From: horizon-commits at lists.jboss.org
> Date: 25 March 2009 15:57:08 GMT
> To: horizon-commits at lists.jboss.org
> Subject: [horizon-commits] Horizon SVN: r40 - in trunk/src/test/java/ 
> org/horizon: expiry and 1 other directories.
> Reply-To: horizon-commits at lists.jboss.org
>
> Author: manik.surtani at jboss.com
> Date: 2009-03-25 11:57:08 -0400 (Wed, 25 Mar 2009)
> New Revision: 40
>
> Modified:
>   trunk/src/test/java/org/horizon/container/ 
> SimpleDataContainerTest.java
>   trunk/src/test/java/org/horizon/expiry/ExpiryTest.java
>   trunk/src/test/java/org/horizon/expiry/ReplicatedExpiryTest.java
>   trunk/src/test/java/org/horizon/loader/BaseCacheStoreTest.java
> Log:
> Expiry can now be set either as an absolute lifespan or a maxIdle time
>
> Modified: trunk/src/test/java/org/horizon/container/ 
> SimpleDataContainerTest.java
> ===================================================================
> --- trunk/src/test/java/org/horizon/container/ 
> SimpleDataContainerTest.java	2009-03-25 12:43:13 UTC (rev 39)
> +++ trunk/src/test/java/org/horizon/container/ 
> SimpleDataContainerTest.java	2009-03-25 15:57:08 UTC (rev 40)
> @@ -4,6 +4,7 @@
> import org.horizon.container.entries.InternalCacheEntry;
> import org.horizon.container.entries.TransientCacheEntry;
> import org.horizon.container.entries.MortalCacheEntry;
> +import org.horizon.container.entries.ImmortalCacheEntry;
>
> import java.util.HashSet;
> import java.util.Set;
> @@ -45,6 +46,40 @@
>       assert dc.size() == 0;
>    }
>
> +   public void testUpdatingLastUsed() throws Exception {
> +      long idle = 600000;
> +      SimpleDataContainer dc = new SimpleDataContainer();
> +      dc.put("k", "v", -1, -1);
> +      InternalCacheEntry ice = dc.get("k");
> +      assert ice instanceof ImmortalCacheEntry;
> +      assert ice.getExpiryTime() == -1;
> +      assert ice.getLastUsed() == -1;
> +      assert ice.getCreated() == -1;
> +      assert ice.getMaxIdle() == -1;
> +      assert ice.getLifespan() == -1;
> +      dc.put("k", "v", -1, idle);
> +      long oldTime = System.currentTimeMillis();
> +      Thread.sleep(10); // for time calc granularity
> +      ice = dc.get("k");
> +      assert ice instanceof TransientCacheEntry;
> +      assert ice.getExpiryTime() == -1;
> +      assert ice.getLastUsed() > oldTime;
> +      Thread.sleep(10); // for time calc granularity
> +      assert ice.getLastUsed() < System.currentTimeMillis();
> +      assert ice.getMaxIdle() == idle;
> +      assert ice.getCreated() == -1;
> +      assert ice.getLifespan() == -1;
> +
> +      oldTime = System.currentTimeMillis();
> +      Thread.sleep(10); // for time calc granularity
> +      assert dc.containsKey("k");
> +
> +      // check that the last used stamp has been updated on a get
> +      assert ice.getLastUsed() > oldTime;
> +      Thread.sleep(10); // for time calc granularity
> +      assert ice.getLastUsed() < System.currentTimeMillis();
> +   }
> +
>    public void testExpirableToImmortal() {
>       SimpleDataContainer dc = new SimpleDataContainer();
>       dc.put("k", "v", 6000000, -1);
>
> Modified: trunk/src/test/java/org/horizon/expiry/ExpiryTest.java
> ===================================================================
> --- trunk/src/test/java/org/horizon/expiry/ExpiryTest.java	 
> 2009-03-25 12:43:13 UTC (rev 39)
> +++ trunk/src/test/java/org/horizon/expiry/ExpiryTest.java	 
> 2009-03-25 15:57:08 UTC (rev 40)
> @@ -12,7 +12,7 @@
>
> import java.util.HashMap;
> import java.util.Map;
> -import java.util.concurrent.TimeUnit;
> +import static java.util.concurrent.TimeUnit.MILLISECONDS;
>
> @Test(groups = "functional", testName = "expiry.ExpiryTest")
> public class ExpiryTest {
> @@ -29,16 +29,17 @@
>       TestingUtil.killCacheManagers(cm);
>    }
>
> -   public void testExpiryInPut() throws InterruptedException {
> +   public void testLifespanExpiryInPut() throws  
> InterruptedException {
>       Cache cache = cm.getCache();
>       long lifespan = 1000;
> -      cache.put("k", "v", lifespan, TimeUnit.MILLISECONDS);
> +      cache.put("k", "v", lifespan, MILLISECONDS);
>
>       DataContainer dc = cache.getAdvancedCache().getDataContainer();
>       InternalCacheEntry se = dc.get("k");
>       assert se.getKey().equals("k");
>       assert se.getValue().equals("v");
>       assert se.getLifespan() == lifespan;
> +      assert se.getMaxIdle() == -1;
>       assert !se.isExpired();
>       assert cache.get("k").equals("v");
>       Thread.sleep(1100);
> @@ -46,14 +47,32 @@
>       assert cache.get("k") == null;
>    }
>
> -   public void testExpiryInPutAll() throws InterruptedException {
> +   public void testIdleExpiryInPut() throws InterruptedException {
>       Cache cache = cm.getCache();
> +      long idleTime = 1000;
> +      cache.put("k", "v", -1, MILLISECONDS, idleTime, MILLISECONDS);
> +
> +      DataContainer dc = cache.getAdvancedCache().getDataContainer();
> +      InternalCacheEntry se = dc.get("k");
> +      assert se.getKey().equals("k");
> +      assert se.getValue().equals("v");
> +      assert se.getLifespan() == -1;
> +      assert se.getMaxIdle() == idleTime;
> +      assert !se.isExpired();
> +      assert cache.get("k").equals("v");
> +      Thread.sleep(1100);
> +      assert se.isExpired();
> +      assert cache.get("k") == null;
> +   }
> +
> +   public void testLifespanExpiryInPutAll() throws  
> InterruptedException {
> +      Cache cache = cm.getCache();
>       long startTime = System.currentTimeMillis();
>       long lifespan = 1000;
>       Map m = new HashMap();
>       m.put("k1", "v");
>       m.put("k2", "v");
> -      cache.putAll(m, lifespan, TimeUnit.MILLISECONDS);
> +      cache.putAll(m, lifespan, MILLISECONDS);
>       while (System.currentTimeMillis() < startTime + lifespan) {
>          assert cache.get("k1").equals("v");
>          assert cache.get("k2").equals("v");
> @@ -68,11 +87,27 @@
>       assert cache.get("k2") == null;
>    }
>
> -   public void testExpiryInPutIfAbsent() throws  
> InterruptedException {
> +   public void testIdleExpiryInPutAll() throws InterruptedException {
>       Cache cache = cm.getCache();
> +      long idleTime = 10000;
> +      Map m = new HashMap();
> +      m.put("k1", "v");
> +      m.put("k2", "v");
> +      cache.putAll(m, -1, MILLISECONDS, idleTime, MILLISECONDS);
> +      assert cache.get("k1").equals("v");
> +      assert cache.get("k2").equals("v");
> +
> +      Thread.sleep(idleTime + 100);
> +
> +      assert cache.get("k1") == null;
> +      assert cache.get("k2") == null;
> +   }
> +
> +   public void testLifespanExpiryInPutIfAbsent() throws  
> InterruptedException {
> +      Cache cache = cm.getCache();
>       long startTime = System.currentTimeMillis();
>       long lifespan = 1000;
> -      assert cache.putIfAbsent("k", "v", lifespan,  
> TimeUnit.MILLISECONDS) == null;
> +      assert cache.putIfAbsent("k", "v", lifespan, MILLISECONDS) ==  
> null;
>       while (System.currentTimeMillis() < startTime + lifespan) {
>          assert cache.get("k").equals("v");
>          Thread.sleep(50);
> @@ -86,19 +121,33 @@
>       assert cache.get("k") == null;
>
>       cache.put("k", "v");
> -      assert cache.putIfAbsent("k", "v", lifespan,  
> TimeUnit.MILLISECONDS) != null;
> +      assert cache.putIfAbsent("k", "v", lifespan, MILLISECONDS) !=  
> null;
>    }
>
> -   public void testExpiryInReplace() throws InterruptedException {
> +   public void testIdleExpiryInPutIfAbsent() throws  
> InterruptedException {
>       Cache cache = cm.getCache();
> +      long idleTime = 10000;
> +      assert cache.putIfAbsent("k", "v", -1, MILLISECONDS,  
> idleTime, MILLISECONDS) == null;
> +      assert cache.get("k").equals("v");
> +
> +      Thread.sleep(idleTime + 100);
> +
> +      assert cache.get("k") == null;
> +
> +      cache.put("k", "v");
> +      assert cache.putIfAbsent("k", "v", -1, MILLISECONDS,  
> idleTime, MILLISECONDS) != null;
> +   }
> +
> +   public void testLifespanExpiryInReplace() throws  
> InterruptedException {
> +      Cache cache = cm.getCache();
>       long lifespan = 1000;
>       assert cache.get("k") == null;
> -      assert cache.replace("k", "v", lifespan,  
> TimeUnit.MILLISECONDS) == null;
> +      assert cache.replace("k", "v", lifespan, MILLISECONDS) == null;
>       assert cache.get("k") == null;
>       cache.put("k", "v-old");
>       assert cache.get("k").equals("v-old");
>       long startTime = System.currentTimeMillis();
> -      assert cache.replace("k", "v", lifespan,  
> TimeUnit.MILLISECONDS) != null;
> +      assert cache.replace("k", "v", lifespan, MILLISECONDS) != null;
>       assert cache.get("k").equals("v");
>       while (System.currentTimeMillis() < startTime + lifespan) {
>          assert cache.get("k").equals("v");
> @@ -115,7 +164,7 @@
>
>       startTime = System.currentTimeMillis();
>       cache.put("k", "v");
> -      assert cache.replace("k", "v", "v2", lifespan,  
> TimeUnit.MILLISECONDS);
> +      assert cache.replace("k", "v", "v2", lifespan, MILLISECONDS);
>       while (System.currentTimeMillis() < startTime + lifespan) {
>          assert cache.get("k").equals("v2");
>          Thread.sleep(50);
> @@ -128,4 +177,25 @@
>       }
>       assert cache.get("k") == null;
>    }
> +
> +   public void testIdleExpiryInReplace() throws  
> InterruptedException {
> +      Cache cache = cm.getCache();
> +      long idleTime = 10000;
> +      assert cache.get("k") == null;
> +      assert cache.replace("k", "v", -1, MILLISECONDS, idleTime,  
> MILLISECONDS) == null;
> +      assert cache.get("k") == null;
> +      cache.put("k", "v-old");
> +      assert cache.get("k").equals("v-old");
> +      assert cache.replace("k", "v", -1, MILLISECONDS, idleTime,  
> MILLISECONDS) != null;
> +      assert cache.get("k").equals("v");
> +
> +      Thread.sleep(idleTime + 100);
> +      assert cache.get("k") == null;
> +
> +      cache.put("k", "v");
> +      assert cache.replace("k", "v", "v2", -1, MILLISECONDS,  
> idleTime, MILLISECONDS);
> +
> +      Thread.sleep(idleTime + 100);
> +      assert cache.get("k") == null;
> +   }
> }
>
> Modified: trunk/src/test/java/org/horizon/expiry/ 
> ReplicatedExpiryTest.java
> ===================================================================
> --- trunk/src/test/java/org/horizon/expiry/ReplicatedExpiryTest.java	 
> 2009-03-25 12:43:13 UTC (rev 39)
> +++ trunk/src/test/java/org/horizon/expiry/ReplicatedExpiryTest.java	 
> 2009-03-25 15:57:08 UTC (rev 40)
> @@ -1,12 +1,16 @@
> package org.horizon.expiry;
>
> import org.horizon.Cache;
> +import org.horizon.container.entries.InternalCacheEntry;
> +import org.horizon.container.entries.TransientMortalCacheEntry;
> +import org.horizon.container.entries.MortalCacheEntry;
> +import org.horizon.container.entries.TransientCacheEntry;
> import org.horizon.config.Configuration;
> import org.horizon.test.MultipleCacheManagersTest;
> import org.testng.annotations.Test;
>
> import java.util.List;
> -import java.util.concurrent.TimeUnit;
> +import static java.util.concurrent.TimeUnit.MILLISECONDS;
>
> @Test(groups = "functional", testName = "expiry.ReplicatedExpiryTest")
> public class ReplicatedExpiryTest extends MultipleCacheManagersTest {
> @@ -20,18 +24,33 @@
>       c2 = caches.get(1);
>    }
>
> -   public void testExpiryReplicates() throws InterruptedException {
> -      long start = System.currentTimeMillis();
> +   public void testLifespanExpiryReplicates() throws  
> InterruptedException {
>       long lifespan = 3000;
> -      c1.put("k", "v", lifespan, TimeUnit.MILLISECONDS);
> +      c1.put("k", "v", lifespan, MILLISECONDS);
> +      InternalCacheEntry ice =  
> c2.getAdvancedCache().getDataContainer().get("k");
>
> -      while (System.currentTimeMillis() < start + lifespan) {
> -         assert c1.get("k").equals("v");
> -         assert c2.get("k").equals("v");
> -         Thread.sleep(250);
> -      }
> -      Thread.sleep(1000);
> -      assert c1.get("k") == null;
> -      assert c2.get("k") == null;
> +      assert ice instanceof MortalCacheEntry;
> +      assert ice.getLifespan() == lifespan;
> +      assert ice.getMaxIdle() == -1;
>    }
> +
> +   public void testIdleExpiryReplicates() throws  
> InterruptedException {
> +      long idle = 3000;
> +      c1.put("k", "v", -1, MILLISECONDS, idle, MILLISECONDS);
> +      InternalCacheEntry ice =  
> c2.getAdvancedCache().getDataContainer().get("k");
> +
> +      assert ice instanceof TransientCacheEntry;
> +      assert ice.getMaxIdle() == idle;
> +      assert ice.getLifespan() == -1;
> +   }
> +
> +   public void testBothExpiryReplicates() throws  
> InterruptedException {
> +      long lifespan = 10000;
> +      long idle = 3000;
> +      c1.put("k", "v", lifespan, MILLISECONDS, idle, MILLISECONDS);
> +      InternalCacheEntry ice =  
> c2.getAdvancedCache().getDataContainer().get("k");
> +      assert ice instanceof TransientMortalCacheEntry;
> +      assert ice.getLifespan() == lifespan;
> +      assert ice.getMaxIdle() == idle;
> +   }
> }
>
> Modified: trunk/src/test/java/org/horizon/loader/ 
> BaseCacheStoreTest.java
> ===================================================================
> --- trunk/src/test/java/org/horizon/loader/BaseCacheStoreTest.java	 
> 2009-03-25 12:43:13 UTC (rev 39)
> +++ trunk/src/test/java/org/horizon/loader/BaseCacheStoreTest.java	 
> 2009-03-25 15:57:08 UTC (rev 40)
> @@ -84,49 +84,101 @@
>       return new ObjectStreamMarshaller();
>    }
>
> -
> -   public void testLoadAndStore() throws InterruptedException,  
> CacheLoaderException {
> +   public void testLoadAndStoreImmortal() throws  
> InterruptedException, CacheLoaderException {
>       assert !cs.containsKey("k");
> -      InternalCacheEntry se = InternalEntryFactory.create("k", "v",  
> -1, -1);
> +      InternalCacheEntry se = InternalEntryFactory.create("k", "v");
>       cs.store(se);
>
>       assert cs.load("k").getValue().equals("v");
>       assert cs.load("k").getLifespan() == -1;
> +      assert cs.load("k").getMaxIdle() == -1;
>       assert !cs.load("k").isExpired();
>       assert cs.containsKey("k");
> +   }
>
> -      long now = System.currentTimeMillis();
> +   public void testLoadAndStoreWithLifespan() throws  
> InterruptedException, CacheLoaderException {
> +      assert !cs.containsKey("k");
> +
>       long lifespan = 120000;
> -      se = InternalEntryFactory.create("k", "v", lifespan);
> +      InternalCacheEntry se = InternalEntryFactory.create("k", "v",  
> lifespan);
>       cs.store(se);
>
>       assert cs.load("k").getValue().equals("v");
>       assert cs.load("k").getLifespan() == lifespan;
> +      assert cs.load("k").getMaxIdle() == -1;
>       assert !cs.load("k").isExpired();
>       assert cs.containsKey("k");
>
> -      now = System.currentTimeMillis();
>       lifespan = 1;
>       se = InternalEntryFactory.create("k", "v", lifespan);
>       cs.store(se);
> -      Thread.sleep(100);
> +      Thread.sleep(10);
>       assert se.isExpired();
>       assert cs.load("k") == null;
>       assert !cs.containsKey("k");
>    }
>
> +   public void testLoadAndStoreWithIdle() throws  
> InterruptedException, CacheLoaderException {
> +      assert !cs.containsKey("k");
> +
> +      long idle = 120000;
> +      InternalCacheEntry se = InternalEntryFactory.create("k", "v",  
> -1, idle);
> +      cs.store(se);
> +
> +      assert cs.load("k").getValue().equals("v");
> +      assert cs.load("k").getLifespan() == -1;
> +      assert cs.load("k").getMaxIdle() == idle;
> +      assert !cs.load("k").isExpired();
> +      assert cs.containsKey("k");
> +
> +      idle = 1;
> +      se = InternalEntryFactory.create("k", "v", -1, idle);
> +      cs.store(se);
> +      Thread.sleep(10);
> +      assert se.isExpired();
> +      assert cs.load("k") == null;
> +      assert !cs.containsKey("k");
> +   }
> +
> +   public void testLoadAndStoreWithLifespanAndIdle() throws  
> InterruptedException, CacheLoaderException {
> +      assert !cs.containsKey("k");
> +
> +      long lifespan = 200000;
> +      long idle = 120000;
> +      InternalCacheEntry se = InternalEntryFactory.create("k", "v",  
> lifespan, idle);
> +      cs.store(se);
> +
> +      assert cs.load("k").getValue().equals("v");
> +      assert cs.load("k").getLifespan() == lifespan;
> +      assert cs.load("k").getMaxIdle() == idle;
> +      assert !cs.load("k").isExpired();
> +      assert cs.containsKey("k");
> +
> +      idle = 1;
> +      se = InternalEntryFactory.create("k", "v", lifespan, idle);
> +      cs.store(se);
> +      Thread.sleep(10);
> +      assert se.isExpired();
> +      assert cs.load("k") == null;
> +      assert !cs.containsKey("k");
> +   }
> +
>    public void testStopStartDoesntNukeValues() throws  
> InterruptedException, CacheLoaderException {
>       assert !cs.containsKey("k1");
>       assert !cs.containsKey("k2");
>
> -      long now = System.currentTimeMillis();
>       long lifespan = 1;
> +      long idle = 1;
>       InternalCacheEntry se1 = InternalEntryFactory.create("k1",  
> "v1", lifespan);
>       InternalCacheEntry se2 = InternalEntryFactory.create("k2",  
> "v2");
> +      InternalCacheEntry se3 = InternalEntryFactory.create("k3",  
> "v3", -1, idle);
> +      InternalCacheEntry se4 = InternalEntryFactory.create("k4",  
> "v4", lifespan, idle);
>
>       cs.store(se1);
>       cs.store(se2);
> -      Thread.sleep(100);
> +      cs.store(se3);
> +      cs.store(se4);
> +      Thread.sleep(10);
>       cs.stop();
>       cs.start();
>       assert se1.isExpired();
> @@ -135,7 +187,12 @@
>       assert cs.load("k2") != null;
>       assert cs.containsKey("k2");
>       assert cs.load("k2").getValue().equals("v2");
> -
> +      assert se3.isExpired();
> +      assert cs.load("k3") == null;
> +      assert !cs.containsKey("k3");
> +      assert se3.isExpired();
> +      assert cs.load("k3") == null;
> +      assert !cs.containsKey("k3");
>    }
>
>
> @@ -246,11 +303,11 @@
>
>    public void  
> testRollbackFromADifferentThreadReusingTransactionKey() throws  
> CacheLoaderException, InterruptedException {
>
> -      cs.store(InternalEntryFactory.create("old", "old", -1, -1));
> +      cs.store(InternalEntryFactory.create("old", "old"));
>
>       List<Modification> mods = new ArrayList<Modification>();
> -      mods.add(new Store(InternalEntryFactory.create("k1", "v1",  
> -1, -1)));
> -      mods.add(new Store(InternalEntryFactory.create("k2", "v2",  
> -1, -1)));
> +      mods.add(new Store(InternalEntryFactory.create("k1", "v1")));
> +      mods.add(new Store(InternalEntryFactory.create("k2", "v2")));
>       mods.add(new Remove("k1"));
>       mods.add(new Remove("old"));
>       final Transaction tx =  
> EasyMock.createNiceMock(Transaction.class);
> @@ -350,13 +407,14 @@
>
>    public void testPurgeExpired() throws Exception {
>       long lifespan = 1000;
> +      long idle = 500;
>       cs.store(InternalEntryFactory.create("k1", "v1", lifespan));
> -      cs.store(InternalEntryFactory.create("k2", "v2", lifespan));
> -      cs.store(InternalEntryFactory.create("k3", "v3", lifespan));
> +      cs.store(InternalEntryFactory.create("k2", "v2", -1, idle));
> +      cs.store(InternalEntryFactory.create("k3", "v3", lifespan,  
> idle));
>       assert cs.containsKey("k1");
>       assert cs.containsKey("k2");
>       assert cs.containsKey("k3");
> -      Thread.sleep(lifespan + 100);
> +      Thread.sleep(lifespan + 10);
>       cs.purgeExpired();
>       assert !cs.containsKey("k1");
>       assert !cs.containsKey("k2");
>
> _______________________________________________
> horizon-commits mailing list
> horizon-commits at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/horizon-commits

--
Manik Surtani
Lead, JBoss Cache
http://www.jbosscache.org
manik at jboss.org




-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jbosscache-dev/attachments/20090325/baf199d4/attachment.html 


More information about the jbosscache-dev mailing list