- fix inconsistent getCacheCheckFrequency time unit: set in global default cache service
check frequency to milliseconds as expected (e.g. in calling wait and other services, fix CacheTest#getCacheRefresh).
- explain timetolive field has setter getTTL
- add example / allow optional disk cache usage test for jcs
git-svn-id: https://svn.apache.org/repos/asf/turbine/fulcrum/trunk/cache@1890338 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index ae7aada..32f2bcd 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -25,10 +25,14 @@
<body>
<release version="1.1.1" date="in subversion">
+ <action dev="gk" type="update">
+ Backward-incompatible change: Global default cache frequency setting is now in milliseconds,
+ as already the ehcache and the JCS.
+ </action>
<action dev="gk" type="update">
- Test: Use tags to skip long running tests, minor fixes in log4j2 configuration and test assertion.
- Update tests to JUnit 5 and dependencies to Fulcrum Testcontainer 1.0.9 and Turbine Parent 8
- - Updated EHCache to v2.10.9.2
+ - Updated EHCache to v2.10.9.2.
</action>
<action dev="gk" type="update">
Update JCS to commons-jcs3-core
diff --git a/src/java/org/apache/fulcrum/cache/CachedObject.java b/src/java/org/apache/fulcrum/cache/CachedObject.java
index 73dffd0..534d2f5 100644
--- a/src/java/org/apache/fulcrum/cache/CachedObject.java
+++ b/src/java/org/apache/fulcrum/cache/CachedObject.java
@@ -54,13 +54,13 @@
private T contents = null;
/** Default age (30 minutes). */
- private final long defaultAge = 1_800_000;
+ private static final long DEFAULT_AGE = 1_800_000;
/** When the object is created. */
- protected long created = 0;
+ protected long created;
/** When the object should expire. */
- private long expires = 0;
+ private long expires;
/** Is this object stale/expired? */
private final AtomicBoolean stale = new AtomicBoolean();
@@ -71,7 +71,7 @@
* @param object
* The object you want to cache.
*/
- public CachedObject(T object)
+ public CachedObject(final T object)
{
this(object, DEFAULT);
}
@@ -85,11 +85,11 @@
* How long before the object expires, in ms, e.g. 1000 = 1
* second.
*/
- public CachedObject(T object, long expires)
+ public CachedObject(final T object, final long expires)
{
if (expires == DEFAULT)
{
- this.expires = this.defaultAge;
+ this.expires = this.DEFAULT_AGE;
} else {
this.expires = expires;
}
@@ -135,11 +135,11 @@
* @param expires
* Expiration interval in millis ( 1 second = 1000 millis)
*/
- public void setExpires(long expires)
+ public void setExpires(final long expires)
{
if (expires == DEFAULT)
{
- this.expires = this.defaultAge;
+ this.expires = this.DEFAULT_AGE;
}
else
{
@@ -161,7 +161,7 @@
* @param stale
* Whether the object is stale or not.
*/
- public void setStale(boolean stale)
+ public void setStale(final boolean stale)
{
this.stale.set( stale );
}
diff --git a/src/java/org/apache/fulcrum/cache/RefreshableCachedObject.java b/src/java/org/apache/fulcrum/cache/RefreshableCachedObject.java
index 27e388c..a563eb2 100644
--- a/src/java/org/apache/fulcrum/cache/RefreshableCachedObject.java
+++ b/src/java/org/apache/fulcrum/cache/RefreshableCachedObject.java
@@ -46,13 +46,16 @@
/**
* How long to wait before removing an untouched object from the cache.
* Negative numbers mean never remove (the default).
+ *
+ * time to live in millisec, getter/setter ({@link #getTTL()}
+ *
*/
- private transient long timeToLive = -1;
+ private long timeToLive = -1;
/**
* The last time the Object was accessed from the cache.
*/
- private transient long lastAccess;
+ private long lastAccess;
/**
* Constructor; sets the object to expire in the default time (30 minutes).
@@ -60,10 +63,10 @@
* @param object
* The object you want to cache.
*/
- public RefreshableCachedObject(T object)
+ public RefreshableCachedObject(final T object)
{
super(object);
- this.lastAccess = System.currentTimeMillis();
+ setLastAccess(System.currentTimeMillis());
}
/**
@@ -75,10 +78,10 @@
* How long before the object expires, in ms, e.g. 1000 = 1
* second.
*/
- public RefreshableCachedObject(T object, long expires)
+ public RefreshableCachedObject(final T object, final long expires)
{
super(object, expires);
- this.lastAccess = System.currentTimeMillis();
+ setLastAccess(System.currentTimeMillis());
}
/**
@@ -87,9 +90,11 @@
* @param timeToLive
* the new Value in milliseconds
*/
- public synchronized void setTTL(long timeToLive)
+ public void setTTL(final long timeToLive)
{
- this.timeToLive = timeToLive;
+ synchronized(this) {
+ this.timeToLive = timeToLive;
+ }
}
/**
@@ -97,17 +102,21 @@
*
* @return The current timeToLive value (in milliseconds)
*/
- public synchronized long getTTL()
+ public long getTTL()
{
- return this.timeToLive;
+ synchronized(this) {
+ return this.timeToLive;
+ }
}
/**
* Sets the last access time to the current time.
*/
- public synchronized void touch()
+ public void touch()
{
- this.lastAccess = System.currentTimeMillis();
+ synchronized(this) {
+ this.lastAccess = System.currentTimeMillis();
+ }
}
/**
@@ -116,14 +125,16 @@
*
* @return boolean status of object
*/
- public synchronized boolean isUntouched()
+ public boolean isUntouched()
{
- boolean untouched = false;
- if (this.lastAccess + this.timeToLive < System.currentTimeMillis())
- {
- untouched = true;
+ boolean untouched = false;
+ synchronized(this) {
+ if (this.lastAccess + this.timeToLive < System.currentTimeMillis())
+ {
+ untouched = true;
+ }
+ return untouched;
}
- return untouched;
}
/**
@@ -138,4 +149,14 @@
refreshable.refresh();
}
}
+
+ public long getLastAccess()
+ {
+ return lastAccess;
+ }
+
+ public void setLastAccess(long lastAccess)
+ {
+ this.lastAccess = lastAccess;
+ }
}
diff --git a/src/java/org/apache/fulcrum/cache/impl/DefaultGlobalCacheService.java b/src/java/org/apache/fulcrum/cache/impl/DefaultGlobalCacheService.java
index f2d04a4..dff4501 100644
--- a/src/java/org/apache/fulcrum/cache/impl/DefaultGlobalCacheService.java
+++ b/src/java/org/apache/fulcrum/cache/impl/DefaultGlobalCacheService.java
@@ -98,6 +98,11 @@
/** flag to stop the housekeeping thread when the component is disposed. */
private transient boolean continueThread;
+
+ public DefaultGlobalCacheService()
+ {
+
+ }
/**
* Get the Cache Check Frequency in milliseconds
@@ -171,7 +176,7 @@
* The object to cache.
*/
@Override
- public <T> void addObject(String objectId, CachedObject<T> object)
+ public <T> void addObject(final String objectId, final CachedObject<T> object)
{
// If the cache already contains the key, remove it and add
// the fresh one.
@@ -336,8 +341,8 @@
@Override
public int getCacheSize() throws IOException
{
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream out = new ObjectOutputStream(baos);
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final ObjectOutputStream out = new ObjectOutputStream(baos);
out.writeObject(this.cache);
out.flush();
//
diff --git a/src/java/org/apache/fulcrum/cache/impl/EHCacheService.java b/src/java/org/apache/fulcrum/cache/impl/EHCacheService.java
index 765c746..6be51bf 100644
--- a/src/java/org/apache/fulcrum/cache/impl/EHCacheService.java
+++ b/src/java/org/apache/fulcrum/cache/impl/EHCacheService.java
@@ -87,6 +87,10 @@
/** A cache instance */
private Cache cache;
+ public EHCacheService()
+ {
+
+ }
// ---------------- Avalon Lifecycle Methods ---------------------
/**
diff --git a/src/java/org/apache/fulcrum/cache/impl/JCSCacheService.java b/src/java/org/apache/fulcrum/cache/impl/JCSCacheService.java
index d7f99f0..3d154e3 100644
--- a/src/java/org/apache/fulcrum/cache/impl/JCSCacheService.java
+++ b/src/java/org/apache/fulcrum/cache/impl/JCSCacheService.java
@@ -90,6 +90,11 @@
/** flag to stop the housekeeping thread when the component is disposed. */
private boolean continueThread;
+
+ public JCSCacheService()
+ {
+
+ }
// ---------------- Avalon Lifecycle Methods ---------------------
@@ -150,7 +155,7 @@
* @see org.apache.fulcrum.cache.GlobalCacheService#getObject(java.lang.String)
*/
@Override
- public <T> CachedObject<T> getObject(String objectId) throws ObjectExpiredException
+ public <T> CachedObject<T> getObject(final String objectId) throws ObjectExpiredException
{
@SuppressWarnings("unchecked")
CachedObject<T> cachedObject = (CachedObject<T>)this.cacheManager.getFromGroup(objectId, group);
@@ -213,9 +218,10 @@
{
getLogger()
.warn(
- "Object with id ["
+ "Object (contents) with id ["
+ objectId
- + "] is not serializable. Expect problems with auxiliary caches.");
+ + "] is not serializable. Expect problems with auxiliary caches: " +
+ cachedObject.getContents().getClass().getSimpleName());
}
ElementAttributes attrib = (ElementAttributes) this.cacheManager.getDefaultElementAttributes();
diff --git a/src/test/TestComponentConfig.xml b/src/test/TestComponentConfig.xml
index 8a262ab..7f48264 100644
--- a/src/test/TestComponentConfig.xml
+++ b/src/test/TestComponentConfig.xml
@@ -18,7 +18,7 @@
under the License.
-->
<componentConfig>
- <cache cacheInitialSize="20" cacheCheckFrequency="5"/>
+ <cache cacheInitialSize="20" cacheCheckFrequency="5000"/>
<ehcache>
<!-- in millisecs -->
<cacheCheckFrequency>5000</cacheCheckFrequency>
diff --git a/src/test/cache.ccf b/src/test/cache.ccf
index e03c134..a7b0c8e 100644
--- a/src/test/cache.ccf
+++ b/src/test/cache.ccf
@@ -16,6 +16,7 @@
# under the License.
# Java Caching System configuration
+# to activate disk cache set to jcs.region.default=DC2
jcs.default=
jcs.default.cacheattributes=org.apache.commons.jcs3.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=1000
@@ -27,13 +28,43 @@
#jcs.default.cacheattributes.MaxSpoolPerRun=500
jcs.default.elementattributes=org.apache.commons.jcs3.engine.ElementAttributes
-# isEternal is assumed by default in Fulcrum Cache
+# isEternal is assumed by default in Fulcrum Cache Refreshable true else false
jcs.default.elementattributes.IsEternal=false
## memory shrinking end
+# not used, only default
jcs.region.fulcrum=
jcs.region.fulcrum.cacheattributes=org.apache.commons.jcs3.engine.CompositeCacheAttributes
jcs.region.fulcrum.cacheattributes.MaxObjects=100
jcs.region.fulcrum.cacheattributes.MemoryCacheName=org.apache.commons.jcs3.engine.memory.lru.LRUMemoryCache
jcs.region.fulcrum.elementattributes=org.apache.commons.jcs3.engine.ElementAttributes
+##############################################################
+################## AUXILIARY CACHES AVAILABLE ################
+
+# Disk Cache Using a Pooled Event Queue -- this allows you
+# to control the maximum number of threads it will use.
+# Each region uses 1 thread by default in the SINGLE model.
+# adding more threads than regions does not help performance.
+# If you want to use a separate pool for each disk cache, either use
+# the single model or define a different auxiliary for each region and use the Pooled type.
+# SINGLE is generally best unless you have a huge # of regions.
+jcs.auxiliary.DC2=org.apache.commons.jcs3.auxiliary.disk.indexed.IndexedDiskCacheFactory
+jcs.auxiliary.DC2.attributes=org.apache.commons.jcs3.auxiliary.disk.indexed.IndexedDiskCacheAttributes
+jcs.auxiliary.DC2.attributes.DiskPath=target/test-sandbox/raf
+jcs.auxiliary.DC2.attributes.MaxPurgatorySize=10000
+jcs.auxiliary.DC2.attributes.MaxKeySize=10000
+jcs.auxiliary.DC2.attributes.OptimizeAtRemoveCount=300000
+jcs.auxiliary.DC2.attributes.OptimizeOnShutdown=true
+jcs.auxiliary.DC2.attributes.EventQueueType=POOLED
+jcs.auxiliary.DC2.attributes.EventQueuePoolName=disk_cache_event_queue
+
+##############################################################
+################## OPTIONAL THREAD POOL CONFIGURATION ########
+
+# Disk Cache Event Queue Pool
+thread_pool.disk_cache_event_queue.useBoundary=false
+thread_pool.disk_cache_event_queue.maximumPoolSize=15
+thread_pool.disk_cache_event_queue.minimumPoolSize=1
+thread_pool.disk_cache_event_queue.keepAliveTime=3500
+thread_pool.disk_cache_event_queue.startUpSize=1
\ No newline at end of file
diff --git a/src/test/org/apache/fulcrum/cache/CacheTest.java b/src/test/org/apache/fulcrum/cache/CacheTest.java
index 04d849c..6c2ab9b 100644
--- a/src/test/org/apache/fulcrum/cache/CacheTest.java
+++ b/src/test/org/apache/fulcrum/cache/CacheTest.java
@@ -290,6 +290,7 @@
// Flush Cache
this.globalCache.flushCache();
// Wait 15 seconds, 3 Refresh
+ // if using disk cache, you might have to wait longer
Thread.sleep((getCacheRefresh() * 2) + 1);
assertEquals( 0, this.globalCache.getNumberOfObjects(),
"After refresh");
@@ -356,6 +357,7 @@
getTestExpireTime());
assertNotNull( cacheObject, "Failed to create a cachable object");
long addTime = System.currentTimeMillis();
+ log.info( "Adding refreshable object to cache: {}", cacheObject );
this.globalCache.addObject(cacheKey, cacheObject);
// Try to get un-expired object
try
@@ -455,7 +457,8 @@
assertEquals(getTestExpireTime(), cacheObject
.getTTL(),
"Returned TimeToLive");
- // Add object to Cache
+ // Add object to Cache
+ log.info( "Adding refreshable object to cache: {}", cacheObject );
this.globalCache.addObject(cacheKey, cacheObject);
long addTime = System.currentTimeMillis();
// Try to get un-expired object
@@ -622,7 +625,7 @@
{
DefaultGlobalCacheService cache =
(DefaultGlobalCacheService)this.lookup(GlobalCacheService.ROLE);
- return cache.getCacheCheckFrequency() * 1000L;
+ return cache.getCacheCheckFrequency();
}
catch (ComponentException e)
{
@@ -633,7 +636,7 @@
/**
* How long until it expires
*
- * @return the cache refresh plus 1000.
+ * @return the cache refresh plus 1000 millisec.
*/
private long getTestExpireTime()
{
diff --git a/xdocs/index.xml b/xdocs/index.xml
index bd608ba..51e0784 100644
--- a/xdocs/index.xml
+++ b/xdocs/index.xml
@@ -87,8 +87,8 @@
<td>[0|1]</td>
<td>
The cache uses a background thread to check for expired objects.
- This defines the time between two checks in seconds. The default
- is 5.
+ This defines the time between two checks in milliseconds. The default
+ is 5000.
</td>
</tr>
</table>
@@ -96,7 +96,7 @@
<subsection name="Component Configuration Example">
<source><![CDATA[
- <cache cacheInitialSize="20" cacheCheckFrequency="5"/>
+ <cache cacheInitialSize="20" cacheCheckFrequency="5000"/>
]]></source>
</subsection>
</section>