[jboss-cvs] JBossAS SVN: r77620 - trunk/cluster/src/main/org/jboss/ha/framework/server/util.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Thu Aug 28 15:43:03 EDT 2008
Author: pferraro
Date: 2008-08-28 15:43:02 -0400 (Thu, 28 Aug 2008)
New Revision: 77620
Modified:
trunk/cluster/src/main/org/jboss/ha/framework/server/util/DistributedTimedCachePolicy.java
Log:
[JBAS-5441] Ensure misc HAPartition-based services can handle concurrent JGroups requests.
Current time property needs to be volatile.
Modified: trunk/cluster/src/main/org/jboss/ha/framework/server/util/DistributedTimedCachePolicy.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/framework/server/util/DistributedTimedCachePolicy.java 2008-08-28 19:31:30 UTC (rev 77619)
+++ trunk/cluster/src/main/org/jboss/ha/framework/server/util/DistributedTimedCachePolicy.java 2008-08-28 19:43:02 UTC (rev 77620)
@@ -46,7 +46,8 @@
@author <a href="mailto:Scott.Stark at jboss.org">Scott Stark</a>.
@version $Revision$
*/
-public class DistributedTimedCachePolicy extends TimerTask
+public class DistributedTimedCachePolicy
+ extends TimerTask
implements CachePolicy
{
/** The interface that cache entries support.
@@ -88,21 +89,21 @@
protected String partitionName;
/** The lifetime in seconds to use for objects inserted
that do not implement the TimedEntry interface. */
- protected int defaultLifetime;
+ protected volatile int defaultLifetime;
/** The caches notion of the current time */
- protected long now;
- /** The resolution in seconds of the cach current time */
+ protected volatile long now;
+ /** The resolution in seconds of the cache current time */
protected int resolution;
/** Creates a new TimedCachePolicy with the given default entry lifetime
that does not synchronized access to its policy store and uses a 60
second resolution.
*/
- public DistributedTimedCachePolicy(String category, String partitionName,
- int defaultLifetime)
+ public DistributedTimedCachePolicy(String category, String partitionName, int defaultLifetime)
{
this(category, partitionName, defaultLifetime, 0);
}
+
/** Creates a new TimedCachePolicy with the given default entry lifetime
that does/does not synchronized access to its policy store depending
on the value of threadSafe.
@@ -117,41 +118,41 @@
updates its notion of the current time every 'resolution' seconds.
@see DistributedState
*/
- public DistributedTimedCachePolicy(String category, String partitionName,
- int defaultLifetime, int resolution)
+ public DistributedTimedCachePolicy(String category, String partitionName, int defaultLifetime, int resolution)
{
this.category = category;
this.partitionName = partitionName;
this.defaultLifetime = defaultLifetime;
- if( resolution <= 0 )
- resolution = 60;
- this.resolution = resolution;
+ this.resolution = (resolution > 0) ? resolution : 60;
}
// Service implementation ----------------------------------------------
/** Initializes the cache for use. Prior to this the cache has no store.
*/
- public void create() throws Exception
+ public void create()
{
// Lookup the parition
- HAPartition partition = HAPartitionLocator.getHAPartitionLocator().getHAPartition(partitionName, null);
+ HAPartition partition = HAPartitionLocator.getHAPartitionLocator().getHAPartition(this.partitionName, null);
this.entryMap = partition.getDistributedStateService();
- log.debug("Obtained DistributedState from partition="+partitionName);
- now = System.currentTimeMillis();
+ log.debug("Obtained DistributedState from partition=" + this.partitionName);
+ this.now = System.currentTimeMillis();
}
+
/** Schedules this with the class resolutionTimer Timer object for
execution every resolution seconds.
*/
public void start()
{
- resolutionTimer.scheduleAtFixedRate(this, 0, 1000*resolution);
+ resolutionTimer.scheduleAtFixedRate(this, 0, 1000 * this.resolution);
}
+
/** Stop cancels the resolution timer and flush()es the cache.
*/
public void stop()
{
super.cancel();
}
+
/** Clears the cache of all entries.
*/
public void destroy()
@@ -167,20 +168,19 @@
public Object get(Object key)
{
Serializable skey = (Serializable) key;
- TimedEntry entry = (TimedEntry) entryMap.get(category, skey);
- if( entry == null )
- return null;
+ TimedEntry entry = (TimedEntry) this.entryMap.get(this.category, skey);
+ if (entry == null) return null;
- if( entry.isCurrent(now) == false )
- { // Try to refresh the entry
- if( entry.refresh() == false )
- { // Failed, remove the entry and return null
+ if (entry.isCurrent(this.now) == false)
+ { // Try to refresh the entry
+ if (entry.refresh() == false)
+ { // Failed, remove the entry and return null
entry.destroy();
try
{
- entryMap.remove(category, skey);
+ this.entryMap.remove(this.category, skey);
}
- catch(Exception e)
+ catch (Exception e)
{
log.debug("Failed to remove expired entry", e);
}
@@ -190,6 +190,7 @@
Object value = entry.getValue();
return value;
}
+
/** Get the cache value for key. This method does not check to see if
the entry has expired.
@return the TimedEntry value or the original value if it was not an
@@ -198,12 +199,15 @@
public Object peek(Object key)
{
Serializable skey = (Serializable) key;
- TimedEntry entry = (TimedEntry) entryMap.get(category, skey);
+ TimedEntry entry = (TimedEntry) this.entryMap.get(this.category, skey);
Object value = null;
- if( entry != null )
+ if (entry != null)
+ {
value = entry.getValue();
+ }
return value;
}
+
/** Insert a value into the cache. In order to have the cache entry
reshresh itself value would have to implement TimedEntry and
implement the required refresh() method logic.
@@ -215,25 +219,27 @@
public void insert(Object key, Object value)
{
Serializable skey = (Serializable) key;
- TimedEntry entry = (TimedEntry) entryMap.get(category, skey);
- if( entry != null )
+ TimedEntry entry = (TimedEntry) this.entryMap.get(this.category, skey);
+ if (entry != null)
+ {
throw new IllegalStateException("Attempt to insert duplicate entry");
- if( (value instanceof TimedEntry) == false )
- { // Wrap the value in a DefaultTimedEntry
+ }
+ if ((value instanceof TimedEntry) == false)
+ { // Wrap the value in a DefaultTimedEntry
Serializable svalue = (Serializable) value;
- entry = new DefaultTimedEntry(defaultLifetime, svalue);
+ entry = new DefaultTimedEntry(this.defaultLifetime, svalue);
}
else
{
entry = (TimedEntry) value;
}
- entry.init(now);
+ entry.init(this.now);
try
{
- entryMap.set(category, skey, entry);
+ this.entryMap.set(this.category, skey, entry);
}
- catch(Exception e)
+ catch (Exception e)
{
log.error("Failed to set entry", e);
}
@@ -247,34 +253,38 @@
Serializable skey = (Serializable) key;
try
{
- TimedEntry entry = (TimedEntry) entryMap.remove(category, skey);
- if( entry != null )
+ TimedEntry entry = (TimedEntry) this.entryMap.remove(this.category, skey);
+ if (entry != null)
+ {
entry.destroy();
+ }
}
- catch(Exception e)
+ catch (Exception e)
{
log.error("Failed to remove entry", e);
}
}
+
/** Remove all entries from the cache.
*/
public void flush()
{
- Collection keys = entryMap.getAllKeys(category);
+ Collection keys = this.entryMap.getAllKeys(this.category);
// Notify the entries of their removal
Iterator iter = keys.iterator();
- while( iter.hasNext() )
+ while (iter.hasNext())
{
Serializable key = (Serializable) iter.next();
- TimedEntry entry = (TimedEntry) entryMap.get(category, key);
+ TimedEntry entry = (TimedEntry) this.entryMap.get(this.category, key);
entry.destroy();
}
}
public int size()
{
- return entryMap.getAllKeys(category).size();
+ return this.entryMap.getAllKeys(this.category).size();
}
+
// --- End CachePolicy interface methods
/** Get the default lifetime of cache entries.
@@ -282,8 +292,9 @@
*/
public int getDefaultLifetime()
{
- return defaultLifetime;
+ return this.defaultLifetime;
}
+
/** Set the default lifetime of cache entries for new values added to the cache.
@param defaultLifetime lifetime in seconds of cache values that do
not implement TimedEntry.
@@ -296,9 +307,10 @@
/** The TimerTask run method. It updates the cache time to the
current system time.
*/
+ @Override
public void run()
{
- now = System.currentTimeMillis();
+ this.now = System.currentTimeMillis();
}
/** Get the cache time.
@@ -306,7 +318,7 @@
*/
public long currentTimeMillis()
{
- return now;
+ return this.now;
}
/** Get the raw TimedEntry for key without performing any expiration check.
@@ -315,7 +327,7 @@
public TimedEntry peekEntry(Object key)
{
Serializable skey = (Serializable) key;
- TimedEntry entry = (TimedEntry) entryMap.get(category, skey);
+ TimedEntry entry = (TimedEntry) this.entryMap.get(this.category, skey);
return entry;
}
@@ -325,6 +337,7 @@
static class DefaultTimedEntry implements TimedEntry
{
long expirationTime;
+
Serializable value;
DefaultTimedEntry(long lifetime, Serializable value)
@@ -332,24 +345,29 @@
this.expirationTime = 1000 * lifetime;
this.value = value;
}
+
public void init(long now)
{
- expirationTime += now;
+ this.expirationTime += now;
}
+
public boolean isCurrent(long now)
{
- return expirationTime > now;
+ return this.expirationTime > now;
}
+
public boolean refresh()
{
return false;
}
+
public void destroy()
{
}
+
public Object getValue()
{
- return value;
+ return this.value;
}
}
}
More information about the jboss-cvs-commits
mailing list