leif 02/03/29 06:03:50
Modified:
instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component
InstrumentComponentHandler.java
InstrumentComponentManager.java
InstrumentComponentSelector.java
InstrumentDefaultComponentFactory.java
instrument-manager/example/conf instrument.xml logkit.xml
Added:
instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component
DefaultComponentHandler.java
PoolableComponentHandler.java
ThreadSafeComponentHandler.java
Log:
Add the ability to profile gets and puts of components.
Revision Changes Path
1.2 +81 -10
jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/InstrumentComponentHandler.java
Index: InstrumentComponentHandler.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/InstrumentComponentHandler.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- InstrumentComponentHandler.java 26 Mar 2002 11:56:16 -0000 1.1
+++ InstrumentComponentHandler.java 29 Mar 2002 14:03:49 -0000 1.2
@@ -7,15 +7,19 @@
*/
package org.apache.avalon.excalibur.instrument.component;
+import org.apache.avalon.excalibur.instrument.Instrument;
+import org.apache.avalon.excalibur.instrument.Instrumentable;
import org.apache.avalon.excalibur.instrument.InstrumentManager;
import org.apache.avalon.excalibur.component.ComponentHandler;
import org.apache.avalon.excalibur.component.DefaultComponentFactory;
-import org.apache.avalon.excalibur.component.DefaultComponentHandler;
-import org.apache.avalon.excalibur.component.PoolableComponentHandler;
+//import org.apache.avalon.excalibur.component.DefaultComponentHandler;
+//import org.apache.avalon.excalibur.component.PoolableComponentHandler;
import org.apache.avalon.excalibur.component.RoleManager;
-import org.apache.avalon.excalibur.component.ThreadSafeComponentHandler;
+//import org.apache.avalon.excalibur.component.ThreadSafeComponentHandler;
import org.apache.avalon.excalibur.logger.LogKitManager;
import org.apache.avalon.excalibur.pool.Poolable;
+
+import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.context.Context;
@@ -25,12 +29,16 @@
/**
*
* @author <a href="mailto:[EMAIL PROTECTED]">Leif Mortenson</a>
- * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
+ * @version CVS $Revision: 1.2 $ $Date: 2002/03/29 14:03:49 $
* @since 4.1
*/
public abstract class InstrumentComponentHandler
extends ComponentHandler
+ implements Instrumentable
{
+ /** Instrumentable Name assigned to this Instrumentable */
+ private String m_instrumentableName = "component-manager";
+
/*---------------------------------------------------------------
* Static Methods
*-------------------------------------------------------------*/
@@ -46,6 +54,7 @@
* @param roleManager The current RoleManager.
* @param logkitManager The current LogKitManager.
* @param instrumentManager The current InstrumentManager.
+ * @param instrumentableName The name of the handler.
*
* @throws Exception If there were any problems obtaining a
ComponentHandler
*/
@@ -56,7 +65,8 @@
final Context context,
final RoleManager roleManager,
final LogKitManager logkitManager,
- final InstrumentManager instrumentManager )
+ final InstrumentManager instrumentManager,
+ final String instrumentableName )
throws Exception
{
int numInterfaces = 0;
@@ -91,18 +101,24 @@
logkitManager,
instrumentManager );
+ InstrumentComponentHandler handler;
if( Poolable.class.isAssignableFrom( componentClass ) )
{
- return new PoolableComponentHandler( factory, config );
+ handler = new PoolableComponentHandler( factory, config );
}
else if( ThreadSafe.class.isAssignableFrom( componentClass ) )
{
- return new ThreadSafeComponentHandler( factory, config );
+ handler = new ThreadSafeComponentHandler( factory, config );
}
else // This is a SingleThreaded component
{
- return new DefaultComponentHandler( factory, config );
+ handler = new DefaultComponentHandler( factory, config );
}
+
+ // Register the new handler with the instrumentManager if it exists.
+ handler.setInstrumentableName( instrumentableName );
+
+ return handler;
}
@@ -115,10 +131,65 @@
public InstrumentComponentHandler()
{
}
-
+
/*---------------------------------------------------------------
- * ComponentHandler Methods
+ * Instrumentable Methods
*-------------------------------------------------------------*/
+ /**
+ * Sets the name for the Instrumentable. The Instrumentable Name is used
+ * to uniquely identify the Instrumentable during the configuration of
+ * the InstrumentManager and to gain access to an
InstrumentableDescriptor
+ * through the InstrumentManager. The value should be a string which
does
+ * not contain spaces or periods.
+ * <p>
+ * This value may be set by a parent Instrumentable, or by the
+ * InstrumentManager using the value of the 'instrumentable' attribute
in
+ * the configuration of the component.
+ *
+ * @param name The name used to identify a Instrumentable.
+ */
+ public void setInstrumentableName( String name )
+ {
+ m_instrumentableName = name;
+ }
+
+ /**
+ * Gets the name of the Instrumentable.
+ *
+ * @return The name used to identify a Instrumentable.
+ */
+ public String getInstrumentableName()
+ {
+ return m_instrumentableName;
+ }
+
+ /*
+ * Obtain a reference to all the Instruments that the Instrumentable
object
+ * wishes to expose. All sampling is done directly through the
+ * Instruments as opposed to the Instrumentable interface.
+ *
+ * @return An array of the Instruments available for profiling. Should
+ * never be null. If there are no Instruments, then
+ * EMPTY_INSTRUMENT_ARRAY can be returned. This should never be
+ * the case though unless there are child Instrumentables with
+ * Instruments.
+ */
+ public abstract Instrument[] getInstruments();
+
+ /**
+ * Any Object which implements Instrumentable can also make use of other
+ * Instrumentable child objects. This method is used to tell the
+ * InstrumentManager about them.
+ *
+ * @return An array of child Instrumentables. This method should never
+ * return null. If there are no child Instrumentables, then
+ * EMPTY_INSTRUMENTABLE_ARRAY can be returned.
+ */
+ public Instrumentable[] getChildInstrumentables()
+ {
+ // Child Instrumenatables are registered as they are found.
+ return Instrumentable.EMPTY_INSTRUMENTABLE_ARRAY;
+ }
/*---------------------------------------------------------------
* Methods
1.2 +102 -4
jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/InstrumentComponentManager.java
Index: InstrumentComponentManager.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/InstrumentComponentManager.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- InstrumentComponentManager.java 26 Mar 2002 11:56:16 -0000 1.1
+++ InstrumentComponentManager.java 29 Mar 2002 14:03:49 -0000 1.2
@@ -7,6 +7,10 @@
*/
package org.apache.avalon.excalibur.instrument.component;
+import java.util.Collection;
+
+import org.apache.avalon.excalibur.instrument.Instrument;
+import org.apache.avalon.excalibur.instrument.Instrumentable;
import org.apache.avalon.excalibur.instrument.InstrumentManageable;
import org.apache.avalon.excalibur.instrument.InstrumentManager;
import org.apache.avalon.excalibur.component.ComponentHandler;
@@ -19,15 +23,19 @@
/**
*
* @author <a href="mailto:[EMAIL PROTECTED]">Leif Mortenson</a>
- * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
+ * @version CVS $Revision: 1.2 $ $Date: 2002/03/29 14:03:49 $
* @since 4.1
*/
public class InstrumentComponentManager
extends ExcaliburComponentManager
- implements InstrumentManageable
+ implements InstrumentManageable, Instrumentable
{
+ /** Instrument Manager being used by the Component Manager. */
private InstrumentManager m_instrumentManager;
+ /** Instrumentable Name assigned to this Instrumentable */
+ private String m_instrumentableName = "component-manager";
+
/*---------------------------------------------------------------
* Constructors
*-------------------------------------------------------------*/
@@ -76,6 +84,9 @@
{
throw new IllegalStateException( "The InstrumentManager was not
yet set." );
}
+
+ String instrumentableName =
+ configuration.getAttribute( "instrumentable",
configuration.getName() );
return InstrumentComponentHandler.getComponentHandler(
componentClass,
configuration,
@@ -83,11 +94,32 @@
context,
roleManager,
logkitManager,
-
m_instrumentManager );
+
m_instrumentManager,
+
instrumentableName );
}
/*---------------------------------------------------------------
- * Methods
+ * ExcaliburComponentManager Methods
+ *-------------------------------------------------------------*/
+ /**
+ * Initialize the component manager.
+ * <p>
+ * This method calls the super method after registering the component
+ * manager with the InstrumentManager.
+ *
+ * @throws Exception If there are any problems initializing the
+ * ComponentManager.
+ */
+ public void initialize()
+ throws Exception
+ {
+ m_instrumentManager.registerInstrumentable( this,
m_instrumentableName );
+
+ super.initialize();
+ }
+
+ /*---------------------------------------------------------------
+ * InstrumentManageable Methods
*-------------------------------------------------------------*/
/**
* Sets the InstrumentManager for child components. Can be for special
@@ -98,6 +130,72 @@
public void setInstrumentManager( InstrumentManager instrumentManager )
{
m_instrumentManager = instrumentManager;
+ }
+
+ /*---------------------------------------------------------------
+ * Instrumentable Methods
+ *-------------------------------------------------------------*/
+ /**
+ * Sets the name for the Instrumentable. The Instrumentable Name is used
+ * to uniquely identify the Instrumentable during the configuration of
+ * the InstrumentManager and to gain access to an
InstrumentableDescriptor
+ * through the InstrumentManager. The value should be a string which
does
+ * not contain spaces or periods.
+ * <p>
+ * This value may be set by a parent Instrumentable, or by the
+ * InstrumentManager using the value of the 'instrumentable' attribute
in
+ * the configuration of the component.
+ *
+ * @param name The name used to identify a Instrumentable.
+ */
+ public void setInstrumentableName( String name )
+ {
+ m_instrumentableName = name;
+ }
+
+ /**
+ * Gets the name of the Instrumentable.
+ *
+ * @return The name used to identify a Instrumentable.
+ */
+ public String getInstrumentableName()
+ {
+ return m_instrumentableName;
+ }
+
+ /**
+ * Obtain a reference to all the Instruments that the Instrumentable
object
+ * wishes to expose. All sampling is done directly through the
+ * Instruments as opposed to the Instrumentable interface.
+ *
+ * @return An array of the Instruments available for profiling. Should
+ * never be null. If there are no Instruments, then
+ * EMPTY_INSTRUMENT_ARRAY can be returned. This should never be
+ * the case though unless there are child Instrumentables with
+ * Instruments.
+ */
+ public Instrument[] getInstruments()
+ {
+ return Instrumentable.EMPTY_INSTRUMENT_ARRAY;
+ }
+
+ /**
+ * Any Object which implements Instrumentable can also make use of other
+ * Instrumentable child objects. This method is used to tell the
+ * InstrumentManager about them.
+ *
+ * @return An array of child Instrumentables. This method should never
+ * return null. If there are no child Instrumentables, then
+ * EMPTY_INSTRUMENTABLE_ARRAY can be returned.
+ */
+ public Instrumentable[] getChildInstrumentables()
+ {
+ // Get the values. This set is created for this call and thus thread
safe.
+ Collection values = getComponentHandlers().values();
+ Instrumentable[] children = new Instrumentable[ values.size() ];
+ values.toArray( children );
+
+ return children;
}
}
1.2 +80 -3
jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/InstrumentComponentSelector.java
Index: InstrumentComponentSelector.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/InstrumentComponentSelector.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- InstrumentComponentSelector.java 26 Mar 2002 11:56:16 -0000 1.1
+++ InstrumentComponentSelector.java 29 Mar 2002 14:03:49 -0000 1.2
@@ -7,6 +7,10 @@
*/
package org.apache.avalon.excalibur.instrument.component;
+import java.util.Collection;
+
+import org.apache.avalon.excalibur.instrument.Instrument;
+import org.apache.avalon.excalibur.instrument.Instrumentable;
import org.apache.avalon.excalibur.instrument.InstrumentManageable;
import org.apache.avalon.excalibur.instrument.InstrumentManager;
import org.apache.avalon.excalibur.component.ComponentHandler;
@@ -20,15 +24,18 @@
/**
*
* @author <a href="mailto:[EMAIL PROTECTED]">Leif Mortenson</a>
- * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
+ * @version CVS $Revision: 1.2 $ $Date: 2002/03/29 14:03:49 $
* @since 4.1
*/
public class InstrumentComponentSelector
extends ExcaliburComponentSelector
- implements InstrumentManageable
+ implements InstrumentManageable, Instrumentable
{
private InstrumentManager m_instrumentManager;
+ /** Instrumentable Name assigned to this Instrumentable */
+ private String m_instrumentableName;
+
/*---------------------------------------------------------------
* Constructors
*-------------------------------------------------------------*/
@@ -76,13 +83,17 @@
final LogKitManager
logkitManager )
throws Exception
{
+ String instrumentableName =
+ configuration.getAttribute( "instrumentable",
configuration.getAttribute( "name" ) );
+
return InstrumentComponentHandler.getComponentHandler(
componentClass,
configuration,
componentManager,
context,
roleManager,
logkitManager,
-
m_instrumentManager );
+
m_instrumentManager,
+
instrumentableName );
}
/*---------------------------------------------------------------
@@ -97,6 +108,72 @@
public void setInstrumentManager( final InstrumentManager
instrumentManager )
{
m_instrumentManager = instrumentManager;
+ }
+
+ /*---------------------------------------------------------------
+ * Instrumentable Methods
+ *-------------------------------------------------------------*/
+ /**
+ * Sets the name for the Instrumentable. The Instrumentable Name is used
+ * to uniquely identify the Instrumentable during the configuration of
+ * the InstrumentManager and to gain access to an
InstrumentableDescriptor
+ * through the InstrumentManager. The value should be a string which
does
+ * not contain spaces or periods.
+ * <p>
+ * This value may be set by a parent Instrumentable, or by the
+ * InstrumentManager using the value of the 'instrumentable' attribute
in
+ * the configuration of the component.
+ *
+ * @param name The name used to identify a Instrumentable.
+ */
+ public void setInstrumentableName( String name )
+ {
+ m_instrumentableName = name;
+ }
+
+ /**
+ * Gets the name of the Instrumentable.
+ *
+ * @return The name used to identify a Instrumentable.
+ */
+ public String getInstrumentableName()
+ {
+ return m_instrumentableName;
+ }
+
+ /**
+ * Obtain a reference to all the Instruments that the Instrumentable
object
+ * wishes to expose. All sampling is done directly through the
+ * Instruments as opposed to the Instrumentable interface.
+ *
+ * @return An array of the Instruments available for profiling. Should
+ * never be null. If there are no Instruments, then
+ * EMPTY_INSTRUMENT_ARRAY can be returned. This should never be
+ * the case though unless there are child Instrumentables with
+ * Instruments.
+ */
+ public Instrument[] getInstruments()
+ {
+ return Instrumentable.EMPTY_INSTRUMENT_ARRAY;
+ }
+
+ /**
+ * Any Object which implements Instrumentable can also make use of other
+ * Instrumentable child objects. This method is used to tell the
+ * InstrumentManager about them.
+ *
+ * @return An array of child Instrumentables. This method should never
+ * return null. If there are no child Instrumentables, then
+ * EMPTY_INSTRUMENTABLE_ARRAY can be returned.
+ */
+ public Instrumentable[] getChildInstrumentables()
+ {
+ // Get the values. This set is created for this call and thus thread
safe.
+ Collection values = getComponentHandlers().values();
+ Instrumentable[] children = new Instrumentable[ values.size() ];
+ values.toArray( children );
+
+ return children;
}
}
1.2 +5 -4
jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/InstrumentDefaultComponentFactory.java
Index: InstrumentDefaultComponentFactory.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/InstrumentDefaultComponentFactory.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- InstrumentDefaultComponentFactory.java 26 Mar 2002 11:56:16 -0000
1.1
+++ InstrumentDefaultComponentFactory.java 29 Mar 2002 14:03:49 -0000
1.2
@@ -21,7 +21,7 @@
* Factory for Avalon Instrumentable components.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Leif Mortenson</a>
- * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
+ * @version CVS $Revision: 1.2 $ $Date: 2002/03/29 14:03:49 $
* @since 4.0
*/
public class InstrumentDefaultComponentFactory
@@ -39,9 +39,10 @@
* @param configuration the <code>Configuration</code> object to pass to
new instances.
* @param componentManager the component manager to pass to
<code>Composable</code>s.
* @param context the <code>Context</code> to pass to
<code>Contexutalizable</code>s.
- * @param roles the <code>RoleManager</code> to pass to
<code>DefaultComponentSelector</code>s.
- * @param instrumentManager the <code>InstrumentManager</code> to
register the component with if
- * it is a Instrumentable.
+ * @param roles the <code>RoleManager</code> to pass to
+ * <code>DefaultComponentSelector</code>s.
+ * @param instrumentManager the <code>InstrumentManager</code> to
register the component
+ * with if it is a Instrumentable.
*/
public InstrumentDefaultComponentFactory( final Class componentClass,
final Configuration
configuration,
1.1
jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/DefaultComponentHandler.java
Index: DefaultComponentHandler.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.avalon.excalibur.instrument.component;
import org.apache.avalon.excalibur.component.DefaultComponentFactory;
import org.apache.avalon.excalibur.component.RoleManager;
import org.apache.avalon.excalibur.instrument.CounterInstrument;
import org.apache.avalon.excalibur.instrument.Instrument;
import org.apache.avalon.excalibur.instrument.ValueInstrument;
import org.apache.avalon.excalibur.logger.LogKitManager;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.context.Context;
import org.apache.log.Logger;
/**
* The DefaultComponentHandler to make sure components are initialized
* and destroyed correctly.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Ryan Shaw</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Leif Mortenson</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/03/29 14:03:49 $
* @since 4.0
*/
public class DefaultComponentHandler
extends InstrumentComponentHandler
{
/** The instance of the ComponentFactory that creates and disposes of the
Component */
private final DefaultComponentFactory m_factory;
/** State management boolean stating whether the Handler is initialized
or not */
private boolean m_initialized = false;
/** State management boolean stating whether the Handler is disposed or
not */
private boolean m_disposed = false;
/** Instrument used to profile the number of outstanding references. */
private ValueInstrument m_referencesInstrument;
/** Instrument used to profile the number of gets. */
private CounterInstrument m_getsInstrument;
/** Instrument used to profile the number of puts. */
private CounterInstrument m_putsInstrument;
/**
* Create a DefaultComponentHandler which manages a pool of Components
* created by the specified factory object.
*
* @param factory The factory object which is responsible for creating
the components
* managed by the ComponentHandler.
* @param config The configuration to use to configure the pool.
*/
public DefaultComponentHandler( final DefaultComponentFactory factory,
final Configuration config )
throws Exception
{
m_factory = factory;
// Initialize the Instrumentable elements.
m_referencesInstrument = new ValueInstrument( "references" );
m_getsInstrument = new CounterInstrument( "gets" );
m_putsInstrument = new CounterInstrument( "puts" );
}
/**
* Sets the logger that the ComponentHandler will use.
*/
public void setLogger( final Logger logger )
{
m_factory.setLogger( logger );
super.setLogger( logger );
}
/**
* Initialize the ComponentHandler.
*/
public void initialize()
{
if( m_initialized )
{
return;
}
if( getLogger().isDebugEnabled() )
{
getLogger().debug( "ComponentHandler initialized for: " +
this.m_factory.getCreatedClass().getName() );
}
m_initialized = true;
}
/**
* Get a reference of the desired Component
*/
protected Component doGet()
throws Exception
{
if( !m_initialized )
{
throw new IllegalStateException( "You cannot get a component from
an uninitialized holder." );
}
if( m_disposed )
{
throw new IllegalStateException( "You cannot get a component from
a disposed holder" );
}
Component component = (Component)m_factory.newInstance();
// Notify the instrument manager
m_getsInstrument.increment();
// Reference count will be incremented after this returns
m_referencesInstrument.setValue( getReferences() + 1 );
return component;
}
/**
* Return a reference of the desired Component
*/
protected void doPut( final Component component )
{
if( !m_initialized )
{
throw new IllegalStateException( "You cannot put a component in
an uninitialized holder." );
}
// Notify the instrument manager
m_putsInstrument.increment();
// References decremented before this call.
m_referencesInstrument.setValue( getReferences() );
try
{
m_factory.decommission( component );
}
catch( final Exception e )
{
if( getLogger().isWarnEnabled() )
{
getLogger().warn( "Error decommissioning component: " +
m_factory.getCreatedClass().getName(), e );
}
}
}
/**
* Dispose of the ComponentHandler and any associated Pools and Factories.
*/
public void dispose()
{
try
{
// do nothing here
if( m_factory instanceof Disposable )
{
( (Disposable)m_factory ).dispose();
}
}
catch( final Exception e )
{
if( getLogger().isWarnEnabled() )
{
getLogger().warn( "Error decommissioning component: " +
m_factory.getCreatedClass().getName(), e );
}
}
m_disposed = true;
}
/*---------------------------------------------------------------
* Instrumentable Methods
*-------------------------------------------------------------*/
/**
* Obtain a reference to all the Instruments that the Instrumentable
object
* wishes to expose. All sampling is done directly through the
* Instruments as opposed to the Instrumentable interface.
*
* @return An array of the Instruments available for profiling. Should
* never be null. If there are no Instruments, then
* EMPTY_INSTRUMENT_ARRAY can be returned. This should never be
* the case though unless there are child Instrumentables with
* Instruments.
*/
public Instrument[] getInstruments()
{
return new Instrument[]
{
m_referencesInstrument,
m_getsInstrument,
m_putsInstrument
};
}
}
1.1
jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/PoolableComponentHandler.java
Index: PoolableComponentHandler.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.avalon.excalibur.instrument.component;
import org.apache.avalon.excalibur.component.DefaultComponentFactory;
import org.apache.avalon.excalibur.instrument.CounterInstrument;
import org.apache.avalon.excalibur.instrument.Instrument;
import org.apache.avalon.excalibur.instrument.ValueInstrument;
import org.apache.avalon.excalibur.logger.LogKitManager;
import org.apache.avalon.excalibur.pool.Poolable;
import org.apache.avalon.excalibur.pool.ResourceLimitingPool;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.logger.LogKitLogger;
import org.apache.log.Logger;
/**
* The PoolableComponentHandler to make sure that poolable components are
initialized
* destroyed and pooled correctly.
* <p>
* Components which implement Poolable may be configured to be pooled using
the following
* example configuration. This example assumes that the user component
class MyComp
* implements Poolable.
* <p>
* Configuration Example:
* <pre>
* <my-comp pool-max="8" pool-max-strict="false" pool-blocking="true"
pool-timeout="0"
* pool-trim-interval="0"/>
* </pre>
* <p>
* Roles Example:
* <pre>
* <role name="com.mypkg.MyComponent"
* shorthand="my-comp"
* default-class="com.mypkg.DefaultMyComponent"/>
* </pre>
* <p>
* Configuration Attributes:
* <ul>
* <li>The <code>pool-max</code> attribute is used to set the maximum number
of components which
* will be pooled. See the <code>pool-max-scrict</code> and
<code>pool-blocking</code>
* attributes. (Defaults to "8")</li>
*
* <li>The <code>pool-max-scrict</code> attribute is used to configure
whether the Component
* Manager should allow more than <code>pool-max</code> Poolables to be
looked up at the same
* time. Setting this to true will throw an exception if the
<code>pool-blocking</code> attribute
* is false. A value of false will allow additional instances of the
Component to be created
* to serve requests, but the additional instances will not be pooled.
(Defaults to "false")
*
* <li>The <code>pool-blocking</code> attributes is used to configure whether
the Component Manager
* should block or throw an Exception when more than <code>pool-max</code>
Poolables are looked
* up at the same time. Setting this to true will cause requests to block
until another thread
* releases a Poolable back to the Component Manager. False will cause an
exception to be thrown.
* This attribute is ignored if <code>pool-max-scrict</code> is false.
(Defaults to "true")</li>
*
* <li>The <code>pool-timeout</code> attribute is used to specify the maximum
amount of time in
* milliseconds that a lookup will block for if Poolables are unavailable.
If the timeout expires
* before another thread releases a Poolable back to the Component Managaer
then an Exception
* will be thrown. A value of "0" specifies that the block will never
timeout.
* (Defaults to "0")</li>
*
* <li>The <code>pool-trim-interval</code> attribute is used to
* specify, in milliseconds, how long idle Poolables will be
* maintained in the pool before being closed. For a complete
* explanation on how this works, see [EMAIL PROTECTED]
* org.apache.avalon.excalibur.pool.ResourceLimitingPool#trim()}
* (Defaults to "0", trimming disabled)</li>
*
* <li>The <code>pool-min</code> and <code>pool-grow</code> attributes
* were deprecated as the underlying Pool ([EMAIL PROTECTED]
* org.apache.avalon.excalibur.pool.ResourceLimitingPool}) does not
* make use of them. Configurations which still use these attributes
* will continue to function however, a minimum pool size is no longer
* applicable.
*
* </ul>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Leif Mortenson</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Ryan Shaw</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/03/29 14:03:49 $
* @since 4.0
*/
public class PoolableComponentHandler extends InstrumentComponentHandler
{
/** The default max size of the pool */
public static final int DEFAULT_MAX_POOL_SIZE = 8;
/** The instance of the ComponentFactory that creates and disposes of the
Component */
private final DefaultComponentFactory m_factory;
/** The pool of components for <code>Poolable</code> Components */
private final ResourceLimitingPool m_pool;
/** State management boolean stating whether the Handler is initialized
or not */
private boolean m_initialized = false;
/** State management boolean stating whether the Handler is disposed or
not */
private boolean m_disposed = false;
/** Instrument used to profile the number of outstanding references. */
private ValueInstrument m_referencesInstrument;
/** Instrument used to profile the number of gets. */
private CounterInstrument m_getsInstrument;
/** Instrument used to profile the number of puts. */
private CounterInstrument m_putsInstrument;
/**
* Create a PoolableComponentHandler which manages a pool of Components
* created by the specified factory object.
*
* @param factory The factory object which is responsible for creating
the components
* managed by the ComponentHandler.
* @param config The configuration to use to configure the pool.
*/
public PoolableComponentHandler( final DefaultComponentFactory factory,
final Configuration config )
throws Exception
{
m_factory = factory;
int poolMax = config.getAttributeAsInteger( "pool-max",
DEFAULT_MAX_POOL_SIZE );
boolean poolMaxStrict = config.getAttributeAsBoolean(
"pool-max-strict", false );
boolean poolBlocking = config.getAttributeAsBoolean( "pool-blocking",
true );
long poolTimeout = config.getAttributeAsLong( "pool-timeout", 0 );
long poolTrimInterval = config.getAttributeAsLong(
"pool-trim-interval", 0 );
m_pool = new ResourceLimitingPool( m_factory, poolMax, poolMaxStrict,
poolBlocking,
poolTimeout, poolTrimInterval );
// Initialize the Instrumentable elements.
m_referencesInstrument = new ValueInstrument( "references" );
m_getsInstrument = new CounterInstrument( "gets" );
m_putsInstrument = new CounterInstrument( "puts" );
}
/**
* Sets the logger that the ComponentHandler will use.
*/
public void setLogger( final Logger logger )
{
m_factory.setLogger( logger );
m_pool.enableLogging( new LogKitLogger( logger ) );
super.setLogger( logger );
}
/**
* Initialize the ComponentHandler.
*/
public void initialize()
{
if( m_initialized )
{
return;
}
if( getLogger().isDebugEnabled() )
{
getLogger().debug( "ComponentHandler initialized for: " +
m_factory.getCreatedClass().getName() );
}
m_initialized = true;
}
/**
* Get a reference of the desired Component
*/
protected Component doGet()
throws Exception
{
if( !m_initialized )
{
throw new IllegalStateException( "You cannot get a component from
an " +
"uninitialized holder." );
}
if( m_disposed )
{
throw new IllegalStateException( "You cannot get a component from
" +
"a disposed holder" );
}
Component component = (Component)m_pool.get();
// Notify the instrument manager
m_getsInstrument.increment();
// Reference count will be incremented after this returns
m_referencesInstrument.setValue( getReferences() + 1 );
return component;
}
/**
* Return a reference of the desired Component
*/
protected void doPut( final Component component )
{
if( !m_initialized )
{
throw new IllegalStateException( "You cannot put a component in "
+
"an uninitialized holder." );
}
// Notify the instrument manager
m_putsInstrument.increment();
// References decremented before this call.
m_referencesInstrument.setValue( getReferences() );
m_pool.put( (Poolable)component );
}
/**
* Dispose of the ComponentHandler and any associated Pools and Factories.
*/
public void dispose()
{
m_pool.dispose();
if( m_factory instanceof Disposable )
{
( (Disposable)m_factory ).dispose();
}
m_disposed = true;
}
/*---------------------------------------------------------------
* Instrumentable Methods
*-------------------------------------------------------------*/
/**
* Obtain a reference to all the Instruments that the Instrumentable
object
* wishes to expose. All sampling is done directly through the
* Instruments as opposed to the Instrumentable interface.
*
* @return An array of the Instruments available for profiling. Should
* never be null. If there are no Instruments, then
* EMPTY_INSTRUMENT_ARRAY can be returned. This should never be
* the case though unless there are child Instrumentables with
* Instruments.
*/
public Instrument[] getInstruments()
{
return new Instrument[]
{
m_referencesInstrument,
m_getsInstrument,
m_putsInstrument
};
}
}
1.1
jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/ThreadSafeComponentHandler.java
Index: ThreadSafeComponentHandler.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.avalon.excalibur.instrument.component;
import org.apache.avalon.excalibur.component.DefaultComponentFactory;
import org.apache.avalon.excalibur.instrument.CounterInstrument;
import org.apache.avalon.excalibur.instrument.Instrument;
import org.apache.avalon.excalibur.instrument.ValueInstrument;
import org.apache.avalon.excalibur.logger.LogKitManager;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.context.Context;
import org.apache.log.Logger;
/**
* The ThreadSafeComponentHandler to make sure components are initialized
* and destroyed correctly.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Ryan Shaw</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Leif Mortenson</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/03/29 14:03:49 $
* @since 4.0
*/
public class ThreadSafeComponentHandler
extends InstrumentComponentHandler
{
private Component m_instance;
private final DefaultComponentFactory m_factory;
private boolean m_initialized = false;
private boolean m_disposed = false;
/** Instrument used to profile the number of outstanding references. */
private ValueInstrument m_referencesInstrument;
/** Instrument used to profile the number of gets. */
private CounterInstrument m_getsInstrument;
/** Instrument used to profile the number of puts. */
private CounterInstrument m_putsInstrument;
/**
* Create a ThreadSafeComponentHandler which manages a pool of Components
* created by the specified factory object.
*
* @param factory The factory object which is responsible for creating
the components
* managed by the ComponentHandler.
* @param config The configuration to use to configure the pool.
*/
public ThreadSafeComponentHandler( final DefaultComponentFactory factory,
final Configuration config )
throws Exception
{
m_factory = factory;
// Initialize the Instrumentable elements.
m_referencesInstrument = new ValueInstrument( "references" );
m_getsInstrument = new CounterInstrument( "gets" );
m_putsInstrument = new CounterInstrument( "puts" );
}
/**
* Create a ComponentHandler that takes care of hiding the details of
* whether a Component is ThreadSafe, Poolable, or SingleThreaded.
* It falls back to SingleThreaded if not specified.
*/
/* Don't need this?
protected ThreadSafeComponentHandler( final Component component )
throws Exception
{
m_instance = component;
m_factory = null;
}
*/
public void setLogger( Logger log )
{
if( this.m_factory != null )
{
m_factory.setLogger( log );
}
super.setLogger( log );
}
/**
* Initialize the ComponentHandler.
*/
public void initialize()
throws Exception
{
if( m_initialized )
{
return;
}
if( m_instance == null )
{
m_instance = (Component)this.m_factory.newInstance();
}
if( getLogger().isDebugEnabled() )
{
if( this.m_factory != null )
{
getLogger().debug( "ComponentHandler initialized for: " +
this.m_factory.getCreatedClass().getName() );
}
else
{
getLogger().debug( "ComponentHandler initialized for: " +
this.m_instance.getClass().getName() );
}
}
m_initialized = true;
}
/**
* Get a reference of the desired Component
*/
protected final Component doGet()
throws Exception
{
if( !m_initialized )
{
throw new IllegalStateException( "You cannot get a component from
an uninitialized holder." );
}
if( m_disposed )
{
throw new IllegalStateException( "You cannot get a component from
a disposed holder" );
}
// Notify the instrument manager
m_getsInstrument.increment();
// Reference count will be incremented after this returns
m_referencesInstrument.setValue( getReferences() + 1 );
return m_instance;
}
/**
* Return a reference of the desired Component
*/
protected void doPut( final Component component )
{
if( !m_initialized )
{
throw new IllegalStateException( "You cannot put a component in
an uninitialized holder." );
}
// Notify the instrument manager
m_putsInstrument.increment();
// References decremented before this call.
m_referencesInstrument.setValue( getReferences() );
}
/**
* Dispose of the ComponentHandler and any associated Pools and Factories.
*/
public void dispose()
{
try
{
if( null != m_factory )
{
m_factory.decommission( m_instance );
}
else
{
if( m_instance instanceof Startable )
{
( (Startable)m_instance ).stop();
}
if( m_instance instanceof Disposable )
{
( (Disposable)m_instance ).dispose();
}
}
m_instance = null;
}
catch( final Exception e )
{
if( getLogger().isWarnEnabled() )
{
getLogger().warn( "Error decommissioning component: " +
m_factory.getCreatedClass().getName(), e );
}
}
m_disposed = true;
}
/*---------------------------------------------------------------
* Instrumentable Methods
*-------------------------------------------------------------*/
/**
* Obtain a reference to all the Instruments that the Instrumentable
object
* wishes to expose. All sampling is done directly through the
* Instruments as opposed to the Instrumentable interface.
*
* @return An array of the Instruments available for profiling. Should
* never be null. If there are no Instruments, then
* EMPTY_INSTRUMENT_ARRAY can be returned. This should never be
* the case though unless there are child Instrumentables with
* Instruments.
*/
public Instrument[] getInstruments()
{
return new Instrument[]
{
m_referencesInstrument,
m_getsInstrument,
m_putsInstrument
};
}
}
1.2 +12 -0
jakarta-avalon-excalibur/instrument-manager/example/conf/instrument.xml
Index: instrument.xml
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/instrument-manager/example/conf/instrument.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- instrument.xml 26 Mar 2002 11:56:15 -0000 1.1
+++ instrument.xml 29 Mar 2002 14:03:49 -0000 1.2
@@ -3,6 +3,18 @@
<instrumentables>
<!-- The profiler Profilable is the ProfilerManager itself. -->
+ <instrumentable name="component-manager">
+ <instrument name="example-instrumentable.puts">
+ <sample type="ctr" interval="1000" size="600"/>
+ </instrument>
+ <instrument name="example-instrumentable.gets">
+ <sample type="ctr" interval="1000" size="600"/>
+ </instrument>
+ <instrument name="example-instrumentable.references">
+ <sample type="max" interval="1000" size="600"/>
+ </instrument>
+ </instrumentable>
+
<instrumentable name="instrument-manager" description="Instrument
Manager">
<instrument name="active-thread-count" description="Active
Thread Count">
<sample type="max" interval="1000" size="600"
description="Maximum each second."/>
1.2 +1 -1
jakarta-avalon-excalibur/instrument-manager/example/conf/logkit.xml
Index: logkit.xml
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/instrument-manager/example/conf/logkit.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- logkit.xml 26 Mar 2002 11:56:16 -0000 1.1
+++ logkit.xml 29 Mar 2002 14:03:49 -0000 1.2
@@ -17,7 +17,7 @@
</targets>
<categories>
<!-- Profiler Manager Logger -->
- <category name="im" log-level="INFO">
+ <category name="im" log-level="DEBUG">
<log-target id-ref="console"/>
<!-- The values child logger can dump out a lot of data. -->
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>