You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jcs-dev@jakarta.apache.org by as...@apache.org on 2005/01/06 02:19:51 UTC
cvs commit: jakarta-turbine-jcs/src/java/org/apache/jcs/utils/threadpool ThreadPoolManager.java
asmuts 2005/01/05 17:19:51
Modified: src/test/org/apache/jcs/access TestCacheAccess.java
src/scripts tester.sh
src/test/org/apache/jcs/engine/memory/lru
TestLRUMemoryCache.java
Added: src/java/org/apache/jcs/engine/stats StatElement.java
Stats.java
src/java/org/apache/jcs/utils/threadpool
ThreadPoolManager.java
Removed: src/test TestBDBJEDiskCacheCon.ccf TestDiskCache.ccf
TestDiskCacheCon.ccf TestDiskCacheNoMemory.ccf
TestTCPLateralCache.ccf
Log:
1. Put in a solution for the RMI bug. Now, gets can be done asynchronously with a configurable timeout.
You can specify that your remote region should timeout gets.
see the cache.ccf in the src/conf for details
#-1 means no timeout, this is the default
# if the timeout is -1, no threadpool will be used.
jcs.auxiliary.RC.attributes.GetTimeoutMillis=5000
jcs.auxiliary.RC.attributes.ThreadPoolName=remote_cache_client
Here RC is my auxiliary name. I tell it to time out at 5 seconds and to use the thread pool named remote_cache_client.
You can define pools in the file. Below I define defaults for a thread pool and the settings for the pool I want the remote cache
client to use.
If the timeout is less than 0, no threadpool will be used.
##############################################################
################## THREAD POOL CONFIGURATION ###################
# default thread pool config
thread_pool.default.boundarySize=75
thread_pool.default.maximumPoolSize=150
thread_pool.default.minimumPoolSize=4
thread_pool.default.keepAliveTime=350000
thread_pool.default.abortWhenBlocked=false
thread_pool.default.startUpSize=4
# remote cache client thread pool config
thread_pool.remote_cache_client.boundarySize=75
thread_pool.remote_cache_client.maximumPoolSize=150
thread_pool.remote_cache_client.minimumPoolSize=4
thread_pool.remote_cache_client.keepAliveTime=350000
thread_pool.remote_cache_client.abortWhenBlocked=false
thread_pool.remote_cache_client.startUpSize=4
2. Changed stats gathering mechanism. I will update the admin jsp to make use of the
more easily formattable data.
Revision Changes Path
1.1 jakarta-turbine-jcs/src/java/org/apache/jcs/engine/stats/StatElement.java
Index: StatElement.java
===================================================================
package org.apache.jcs.engine.stats;
import org.apache.jcs.engine.stats.behavior.IStatElement;
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author aaronsm
*
*/
public class StatElement implements IStatElement {
private String name = null;
private String data = null;
/* (non-Javadoc)
* @see org.apache.jcs.engine.stats.behavior.IStatElement#getName()
*/
public String getName() {
return name;
}
/* (non-Javadoc)
* @see org.apache.jcs.engine.stats.behavior.IStatElement#setName(java.lang.String)
*/
public void setName(String name) {
this.name = name;
}
/* (non-Javadoc)
* @see org.apache.jcs.engine.stats.behavior.IStatElement#getData()
*/
public String getData() {
return data;
}
/* (non-Javadoc)
* @see org.apache.jcs.engine.stats.behavior.IStatElement#setData(java.lang.String)
*/
public void setData(String data) {
this.data = data;
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString()
{
StringBuffer buf = new StringBuffer();
buf.append( name + " = " + data );
return buf.toString();
}
}
1.1 jakarta-turbine-jcs/src/java/org/apache/jcs/engine/stats/Stats.java
Index: Stats.java
===================================================================
package org.apache.jcs.engine.stats;
import org.apache.jcs.engine.stats.behavior.IStatElement;
import org.apache.jcs.engine.stats.behavior.IStats;
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author aaronsm
*
*/
public class Stats implements IStats {
private IStatElement[] stats = null;
private String typeName = null;
/* (non-Javadoc)
* @see org.apache.jcs.engine.stats.behavior.IStats#getStatElements()
*/
public IStatElement[] getStatElements() {
return stats;
}
/* (non-Javadoc)
* @see org.apache.jcs.engine.stats.behavior.IStats#setStatElements(org.apache.jcs.engine.stats.behavior.IStatElement[])
*/
public void setStatElements(IStatElement[] stats) {
this.stats = stats;
}
/* (non-Javadoc)
* @see org.apache.jcs.engine.stats.behavior.IStats#getTypeName()
*/
public String getTypeName() {
return typeName;
}
/* (non-Javadoc)
* @see org.apache.jcs.engine.stats.behavior.IStats#setTypeName(java.lang.String)
*/
public void setTypeName(String name) {
typeName = name;
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString()
{
StringBuffer buf = new StringBuffer();
buf.append( typeName );
if ( stats != null )
{
for( int i = 0; i < stats.length; i++ )
{
buf.append( "\n" );
buf.append( stats[i] );
}
}
return buf.toString();
}
}
1.13 +4 -8 jakarta-turbine-jcs/src/test/org/apache/jcs/access/TestCacheAccess.java
Index: TestCacheAccess.java
===================================================================
RCS file: /home/cvs/jakarta-turbine-jcs/src/test/org/apache/jcs/access/TestCacheAccess.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- TestCacheAccess.java 22 Jul 2004 13:15:16 -0000 1.12
+++ TestCacheAccess.java 6 Jan 2005 01:19:51 -0000 1.13
@@ -18,21 +18,17 @@
import java.io.BufferedReader;
import java.io.InputStreamReader;
-
-import java.util.StringTokenizer;
import java.util.Iterator;
import java.util.Random;
-
-import org.apache.jcs.engine.behavior.IElementAttributes;
-import org.apache.jcs.engine.ElementAttributes;
+import java.util.StringTokenizer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-
-import org.apache.jcs.engine.control.event.TestElementEventHandler;
-import org.apache.jcs.engine.control.CompositeCache;
import org.apache.jcs.JCS;
+import org.apache.jcs.engine.ElementAttributes;
+import org.apache.jcs.engine.behavior.IElementAttributes;
import org.apache.jcs.engine.control.CompositeCacheManager;
+import org.apache.jcs.engine.control.event.TestElementEventHandler;
/**
* Allows the user to run common cache commands from the command line for a test
1.2 +5 -7 jakarta-turbine-jcs/src/scripts/tester.sh
Index: tester.sh
===================================================================
RCS file: /home/cvs/jakarta-turbine-jcs/src/scripts/tester.sh,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- tester.sh 5 Jan 2005 00:27:43 -0000 1.1
+++ tester.sh 6 Jan 2005 01:19:51 -0000 1.2
@@ -1,14 +1,12 @@
#!/bin/zsh -f
THIS_DIR=$(dirname $0)
-pushd ${THIS_DIR}/../..;
+export CLASSPATH=${THIS_DIR}/../../src/conf
+export CLASSPATH=${CLASSPATH}:${THIS_DIR}/../../target/test-classes
+export CLASSPATH=${CLASSPATH}:${THIS_DIR}/../../target/classes
+export CLASSPATH=${CLASSPATH}:.
-export CLASSPATH=.
-export CLASSPATH=${CLASSPATH}:${THIS_DIR}/target/test-classes
-export CLASSPATH=${CLASSPATH}:${THIS_DIR}/target/classes
-#export CLASSPATH=${CLASSPATH}:${THIS_DIR}/src/conf
-
-for i in `find ${THIS_DIR}/jars -name "*.jar" `
+for i in `find ${THIS_DIR}/../../jars -name "*.jar" `
do
export CLASSPATH=${CLASSPATH}:$i
done
1.3 +4 -5 jakarta-turbine-jcs/src/test/org/apache/jcs/engine/memory/lru/TestLRUMemoryCache.java
Index: TestLRUMemoryCache.java
===================================================================
RCS file: /home/cvs/jakarta-turbine-jcs/src/test/org/apache/jcs/engine/memory/lru/TestLRUMemoryCache.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- TestLRUMemoryCache.java 15 Apr 2004 19:24:19 -0000 1.2
+++ TestLRUMemoryCache.java 6 Jan 2005 01:19:51 -0000 1.3
@@ -22,11 +22,10 @@
import junit.framework.Test;
import junit.framework.TestCase;
-import org.apache.jcs.JCS;
import org.apache.jcs.engine.CacheElement;
import org.apache.jcs.engine.behavior.ICacheElement;
-import org.apache.jcs.engine.control.CompositeCacheManager;
import org.apache.jcs.engine.control.CompositeCache;
+import org.apache.jcs.engine.control.CompositeCacheManager;
/**
* Test which exercises the indexed disk cache. This one uses three different
@@ -137,7 +136,7 @@
for ( int i = 0; i < 102; i++ )
{
- this.assertNull(lru.get( i + ":key" ));
+ assertNull(lru.get( i + ":key" ));
}
// Test that last items are in cache
@@ -146,7 +145,7 @@
{
String value = (String)
((ICacheElement)lru.get( i + ":key" )).getVal();
- this.assertEquals( region + " data " + i, value );
+ assertEquals( region + " data " + i, value );
}
// Remove all the items
1.1 jakarta-turbine-jcs/src/java/org/apache/jcs/utils/threadpool/ThreadPoolManager.java
Index: ThreadPoolManager.java
===================================================================
package org.apache.jcs.utils.threadpool;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import EDU.oswego.cs.dl.util.concurrent.BoundedBuffer;
import EDU.oswego.cs.dl.util.concurrent.PooledExecutor;
/**
* This manages threadpools for an application using Doug Lea's Util Concurrent
* package.
* http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html
*
* It is a singleton since threads need to be managed vm wide.
*
* This managers force you to use a bounded queue. By default it uses the
* current thread for execuion when the buffer is full and no free threads can
* be created.
*
* You can specify the props file to use or pass in a properties object prior to
* configuration. By default it looks for configuration information in
* thread_pool.properties.
*
* If set the Properties object will take precedence.
*
* If a value is not set for a particular pool, the hard coded defaults will be
* used.
*
* int boundarySize_DEFAULT = 75; int maximumPoolSize_DEFAULT = 150; int
* minimumPoolSize_DEFAULT = 4; int keepAliveTime_DEFAULT = 1000 * 60 * 5;
* boolean abortWhenBlocked = false; int startUpSize_DEFAULT = 4;
*
*
* You can configure default settings by specifying a default pool in the
* properties, ie "cache.ccf"
*
* @author Aaron Smuts
*
*/
public class ThreadPoolManager
{
private static final Log log = LogFactory
.getLog( ThreadPoolManager.class );
// DEFAULT SETTINGS, these are not final since they can be set
// via the Propeties file or object
private static int boundarySize_DEFAULT = 75;
private static int maximumPoolSize_DEFAULT = 150;
private static int minimumPoolSize_DEFAULT = 4;
private static int keepAliveTime_DEFAULT = 1000 * 60 * 5;
private static boolean abortWhenBlocked_DEFAULT = false;
private static int startUpSize_DEFAULT = 4;
private static PoolConfiguration defaultConfig;
// This is the default value. Setting this after
// inialization will have no effect
private static String propsFileName = "cache.ccf";
// the root property name
private static String PROP_NAME_ROOT = "thread_pool";
private static String DEFAULT_PROP_NAME_ROOT = "thread_pool.default";
// You can specify the properties to be used to configure
// the thread pool. Setting this post initialization will have
// no effect.
private static Properties props = null;
private static HashMap pools = new HashMap();
// singleton instance
private static ThreadPoolManager INSTANCE = null;
/**
* No instances please. This is a singleton.
*
*/
private ThreadPoolManager()
{
configure();
}
/**
* Creates a pool based on the configuration info.
*
* @param config
* @return
*/
private PooledExecutor createPool( PoolConfiguration config )
{
PooledExecutor pool = new PooledExecutor( new BoundedBuffer( config
.getBoundarySize() ), config.getMaximumPoolSize() );
pool.setMinimumPoolSize( config.getMinimumPoolSize() );
pool.setKeepAliveTime( config.getKeepAliveTime() );
if (config.isAbortWhenBlocked())
{
pool.abortWhenBlocked();
}
else
{
pool.runWhenBlocked();
}
pool.createThreads( config.getStartUpSize() );
return pool;
}
/**
* Returns a configured instance of the ThreadPoolManger To specify a
* configuation file or Properties object to use call the appropriate setter
* prior to calling getInstance.
*
* @return
*/
public static synchronized ThreadPoolManager getInstance()
{
if (INSTANCE == null)
{
INSTANCE = new ThreadPoolManager();
}
return INSTANCE;
}
/**
* Returns a pool by name. If a pool by this name does not exist in the
* configuration file or properties, one will be created using the default
* values.
*
* Pools are lazily created.
*
*
* @param name
* @return
*/
public PooledExecutor getPool( String name )
{
PooledExecutor pool = null;
synchronized (pools)
{
pool = (PooledExecutor) pools.get( name );
if (pool == null)
{
if (log.isDebugEnabled())
{
log.debug( "Creating pool for name [" + name + "]" );
}
PoolConfiguration config = this
.loadConfig( PROP_NAME_ROOT + "." + name );
pool = createPool( config );
if (pool != null)
{
pools.put( name, pool );
}
if (log.isDebugEnabled())
{
log.debug( "PoolName = " + getPoolNames() );
}
}
}
return pool;
}
/**
* returns the names of all configured pools.
*
* @return ArrayList of string names
*/
public ArrayList getPoolNames()
{
ArrayList poolNames = new ArrayList();
synchronized (pools)
{
Set names = pools.keySet();
Iterator it = names.iterator();
while (it.hasNext())
{
poolNames.add( (String) it.next() );
}
}
return poolNames;
}
/**
* Setting this post initialization will have no effect.
*
* @param propsFileName
* The propsFileName to set.
*/
public static void setPropsFileName( String propsFileName )
{
ThreadPoolManager.propsFileName = propsFileName;
}
/**
*
* @return Returns the propsFileName.
*/
public static String getPropsFileName()
{
return propsFileName;
}
/**
* This will be used if it is not null on initialzation. Setting this post
* initialization will have no effect.
*
* @param props
* The props to set.
*/
public static void setProps( Properties props )
{
ThreadPoolManager.props = props;
}
/**
* @return Returns the props.
*/
public static Properties getProps()
{
return props;
}
//-------------------------- Private Methods ----------
/**
* Intialize the ThreadPoolManager and create all the pools defined in the
* configuration.
*
*/
private void configure()
{
if (log.isDebugEnabled())
{
log.debug( "Initializing ThreadPoolManager" );
}
if (props == null)
{
InputStream is = getClass().getResourceAsStream( "/" + propsFileName );
try
{
props.load( is );
if (log.isDebugEnabled())
{
log.debug( "File contained " + props.size() + " properties" );
}
}
catch (IOException ex)
{
log.error( "Failed to load properties", ex );
throw new IllegalStateException( ex.getMessage() );
}
finally
{
try
{
is.close();
}
catch (Exception ignore)
{
// Ignored
}
}
}
if (props == null)
{
log
.warn( "No configuration settings found. Using hardcoded default values for all pools." );
props = new Properties();
}
// set intial default and then override if new
// settings are available
defaultConfig = new PoolConfiguration( boundarySize_DEFAULT,
maximumPoolSize_DEFAULT, minimumPoolSize_DEFAULT,
keepAliveTime_DEFAULT, abortWhenBlocked_DEFAULT, startUpSize_DEFAULT );
defaultConfig = loadConfig( DEFAULT_PROP_NAME_ROOT );
}
/**
* Configures the default PoolConfiguration settings
*
*/
private PoolConfiguration loadConfig( String root )
{
PoolConfiguration config = (PoolConfiguration) defaultConfig.clone();
// load default if they exist
if (props.containsKey( root + ".boundarySize" ))
{
try
{
config.setBoundarySize( Integer.parseInt( (String) props.get( root
+ ".boundarySize" ) ) );
}
catch (NumberFormatException nfe)
{
log.error( "boundarySize not a number.", nfe );
}
}
if (props.containsKey( root + ".maximumPoolSize" ))
{
try
{
config.setMaximumPoolSize( Integer.parseInt( (String) props.get( root
+ ".maximumPoolSize" ) ) );
}
catch (NumberFormatException nfe)
{
log.error( "maximumPoolSize not a number.", nfe );
}
}
if (props.containsKey( root + ".minimumPoolSize" ))
{
try
{
config.setMinimumPoolSize( Integer.parseInt( (String) props.get( root
+ ".minimumPoolSize" ) ) );
}
catch (NumberFormatException nfe)
{
log.error( "minimumPoolSize not a number.", nfe );
}
}
if (props.containsKey( root + ".keepAliveTime" ))
{
try
{
config.setKeepAliveTime( Integer.parseInt( (String) props.get( root
+ ".keepAliveTime" ) ) );
}
catch (NumberFormatException nfe)
{
log.error( "keepAliveTime not a number.", nfe );
}
}
if (props.containsKey( root + ".startUpSize" ))
{
try
{
config.setAbortWhenBlocked( Boolean.getBoolean( (String) props
.get( root + ".abortWhenBlocked" ) ) );
}
catch (NumberFormatException nfe)
{
log.error( "abortWhenBlocked not a boolean.", nfe );
}
}
if (props.containsKey( root + ".startUpSize" ))
{
try
{
config.setStartUpSize( Integer.parseInt( (String) props.get( root
+ ".startUpSize" ) ) );
}
catch (NumberFormatException nfe)
{
log.error( "startUpSize not a number.", nfe );
}
}
if (log.isDebugEnabled())
{
log.debug( root + " PoolConfiguration = " + config );
}
return config;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: turbine-jcs-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: turbine-jcs-dev-help@jakarta.apache.org