leif 02/03/03 08:00:00
Modified: src/scratchpad/org/apache/avalon/excalibur/datasource
ResourceLimitingJdbcConnectionPool.java
ResourceLimitingJdbcDataSource.java
Log:
New Profiler Implementation
Revision Changes Path
1.4 +180 -13
jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/datasource/ResourceLimitingJdbcConnectionPool.java
Index: ResourceLimitingJdbcConnectionPool.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/datasource/ResourceLimitingJdbcConnectionPool.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ResourceLimitingJdbcConnectionPool.java 26 Feb 2002 07:49:57 -0000
1.3
+++ ResourceLimitingJdbcConnectionPool.java 3 Mar 2002 16:00:00 -0000
1.4
@@ -10,7 +10,12 @@
import org.apache.avalon.excalibur.pool.ValidatedResourceLimitingPool;
import java.sql.SQLException;
+import java.util.HashMap;
+import org.apache.avalon.excalibur.altprofile.CounterProfilePoint;
+import org.apache.avalon.excalibur.altprofile.Profilable;
+import org.apache.avalon.excalibur.altprofile.ProfilePoint;
+import org.apache.avalon.excalibur.altprofile.ValueProfilePoint;
import org.apache.avalon.excalibur.datasource.JdbcConnection;
import org.apache.avalon.excalibur.pool.ObjectFactory;
import org.apache.avalon.excalibur.pool.Poolable;
@@ -24,14 +29,32 @@
* connections.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Leif Mortenson</a>
- * @version CVS $Revision: 1.3 $ $Date: 2002/02/26 07:49:57 $
+ * @version CVS $Revision: 1.4 $ $Date: 2002/03/03 16:00:00 $
* @since 4.1
*/
public class ResourceLimitingJdbcConnectionPool
extends ValidatedResourceLimitingPool
+ implements Profilable
{
+ public static final String DEFAULT_PROFILABLE_NAME = "pool";
+ public static final String PROFILE_POINT_NEW_POOLABLES_NAME =
"new-poolables";
+ public static final String PROFILE_POINT_SIZE_NAME = "size";
+ public static final String PROFILE_POINT_READY_SIZE_NAME =
"ready-size";
+
private boolean m_autoCommit;
+ /** Profilable Name assigned to this Profilable */
+ private String m_profilableName = DEFAULT_PROFILABLE_NAME;
+
+ /** ProfilePoint used to profile the creation of new poolables. */
+ private CounterProfilePoint m_newPoolableProfilePoint;
+
+ /** ProfilePoint used to profile the size of the pool. */
+ private ValueProfilePoint m_poolSizeProfilePoint;
+
+ /** ProfilePoint used to profile the ready size of the pool. */
+ private ValueProfilePoint m_poolReadySizeProfilePoint;
+
/*---------------------------------------------------------------
* Constructors
*-------------------------------------------------------------*/
@@ -59,12 +82,17 @@
boolean blocking,
long blockTimeout,
long trimInterval,
- boolean autoCommit )
+ boolean autoCommit)
{
- super(factory, max, maxStrict, blocking, blockTimeout, trimInterval);
+ super( factory, max, maxStrict, blocking, blockTimeout, trimInterval
);
m_autoCommit = autoCommit;
+
+ // Initialize the Profiler elements.
+ m_newPoolableProfilePoint = new CounterProfilePoint(
PROFILE_POINT_NEW_POOLABLES_NAME );
+ m_poolSizeProfilePoint = new ValueProfilePoint(
PROFILE_POINT_SIZE_NAME );
+ m_poolReadySizeProfilePoint = new ValueProfilePoint(
PROFILE_POINT_READY_SIZE_NAME );
}
/*---------------------------------------------------------------
@@ -75,20 +103,50 @@
* on the pool's ObjectFactory.
* This is the method to override when you need to enforce creational
* policies.
- * This method is only called by threads that have _semaphore locked.
+ * This method is only called by threads that have m_semaphore locked.
*/
protected Poolable newPoolable() throws Exception {
JdbcConnection conn = (JdbcConnection)super.newPoolable();
// Store a reference to this pool in the connection
- conn.setPool(this);
+ conn.setPool( this );
// Set the auto commit flag for new connections.
- conn.setAutoCommit(m_autoCommit);
+ conn.setAutoCommit( m_autoCommit );
+
+ // Notify the Profiler
+ m_newPoolableProfilePoint.increment();
+ if ( m_poolSizeProfilePoint.isActive() )
+ {
+ // Size will not yet have been incremented
+ m_poolSizeProfilePoint.setValue( this.getSize() + 1 );
+ }
return conn;
}
+
+ /**
+ * Called when an object is being removed permanently from the pool.
+ * This is the method to override when you need to enforce destructional
+ * policies.
+ * <p>
+ * This method is only called by threads that have m_semaphore locked.
+ *
+ * @param poolable Poolable to be completely removed from the pool.
+ */
+ protected void removePoolable( Poolable poolable )
+ {
+ super.removePoolable( poolable );
+
+ // Notify the Profiler
+ if ( m_poolSizeProfilePoint.isActive() )
+ {
+ m_poolSizeProfilePoint.setValue( this.getSize() );
+ }
+ }
+
+
/**
* Validates the poolable before it is provided to the caller of get on
this pool.
* This implementation of the validation method always returns true
indicating
@@ -105,24 +163,133 @@
// used for a while. Is this a problem because the m_semaphore
// is currently locked? I am thinking no because isClosed()
will
// return immediately when connections are being used
frequently.
- if (conn.isClosed()) {
- getLogger().debug("JdbcConnection was closed.");
+ if ( conn.isClosed() ) {
+ getLogger().debug( "JdbcConnection was closed." );
return false;
}
} catch (SQLException e) {
getLogger().debug(
- "Failed to check whether JdbcConnection was closed. " +
e.getMessage());
+ "Failed to check whether JdbcConnection was closed. " +
e.getMessage() );
}
return true;
}
- /*---------------------------------------------------------------
- * Public Methods
- *-------------------------------------------------------------*/
+ /**
+ * Gets a Connection from the pool. Depending on the parameters passed
to
+ * the constructor, the call may block of throw an exception if no
+ * Connections are currently available in the pool. Connections
returned
+ * must always be closed. Calling close will cause put to be called on
+ * the pool.
+ *
+ * @returns Always returns a Poolable. Contract requires that put must
+ * always be called with the Poolable returned.
+ *
+ * @throws Exception An exception may be thrown as described above or if
+ * there is an exception thrown by the ObjectFactory's
+ * newInstance() method.
+ */
+ public Poolable get() throws Exception
+ {
+ // Get the connection before notifying the profiler so that calls
+ // which result in an exception will not be counted.
+ Poolable connection = super.get();
+
+ // Notify the Profiler
+ if ( m_poolReadySizeProfilePoint.isActive() )
+ {
+ // Value may be slightly off because of synchronization, but
+ // making it 100% accurate is not worth the performance hit.
+ m_poolReadySizeProfilePoint.setValue( this.getReadySize() );
+ }
+
+ return connection;
+ }
+
+ /**
+ * Returns a connection to the pool.
+ *
+ * @param connection Connection to return to the pool.
+ */
+ public void put( Poolable connection )
+ {
+ // Put the connection back into the pool before notifying the
profiler
+ // so that the pool size will be correct.
+ super.put(connection);
+
+ // Notify the Profiler
+ if ( m_poolReadySizeProfilePoint.isActive() )
+ {
+ // Value may be slightly off because of synchronization, but
+ // making it 100% accurate is not worth the performance hit.
+ m_poolReadySizeProfilePoint.setValue( this.getReadySize() );
+ }
+ }
/*---------------------------------------------------------------
- * Private Methods
+ * Profilable Methods
*-------------------------------------------------------------*/
+ /**
+ * Sets the name for the Profilable. The Profilable Name is used to
+ * uniquely identify the Profilable during the configuration of the
+ * Profiler and to gain access to a ProfilableDescriptor through a
+ * ProfilerManager. The value should be a string which does not
+ * contain spaces or periods.
+ * <p>
+ * This value may be set by a parent Profilable, or by the
ProfilerManager
+ * using the value of the 'profilable' attribute in the configuration
+ * of the component.
+ *
+ * @param name The name used to identify a Profilable.
+ */
+ public void setProfilableName( String name )
+ {
+ m_profilableName = name;
+ }
+
+ /**
+ * Gets the name of the Profilable. The Profilable Name is used to
+ * uniquely identify the Profilable during the configuration of the
+ * Profiler and to gain access to a ProfilableDescriptor through a
+ * ProfilerManager. The value should be a string which does not
+ * contain spaces or periods.
+ *
+ * @return The name used to identify a Profilable.
+ */
+ public String getProfilableName()
+ {
+ return m_profilableName;
+ }
+
+ /**
+ * Obtain a reference to all the ProfilePoints that the Profilable
+ * object wishes to expose. All sampling is done directly through
+ * the ProfilePoints as opposed to the Profilable interface.
+ *
+ * @return An array of the ProfilePoints available for profiling.
+ * Should never be null. If there are no ProfilePoints, then
+ * EMPTY_PROFILE_POINT_ARRAY can be returned. This should
+ * never be the case though unless there are child Profilables
+ * with ProfilePoints.
+ */
+ public ProfilePoint[] getProfilePoints()
+ {
+ return new ProfilePoint[]
+ { m_newPoolableProfilePoint, m_poolSizeProfilePoint,
m_poolReadySizeProfilePoint };
+ }
+
+ /**
+ * Any Object which implements Profilable can also make use of other
+ * Profilable child objects. This method is used to tell the Profiler
+ * about them.
+ *
+ * @return An array of child Profilables. This method should never
+ * return null. If there are no child Profilables, then
+ * EMPTY_PROFILABLE_ARRAY can be returned.
+ */
+ public Profilable[] getChildProfilables()
+ {
+ return Profilable.EMPTY_PROFILABLE_ARRAY;
+ }
}
1.7 +76 -4
jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/datasource/ResourceLimitingJdbcDataSource.java
Index: ResourceLimitingJdbcDataSource.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/datasource/ResourceLimitingJdbcDataSource.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ResourceLimitingJdbcDataSource.java 22 Feb 2002 09:26:21 -0000
1.6
+++ ResourceLimitingJdbcDataSource.java 3 Mar 2002 16:00:00 -0000
1.7
@@ -9,7 +9,10 @@
import java.sql.Connection;
import java.sql.SQLException;
+import java.util.HashMap;
+import org.apache.avalon.excalibur.altprofile.Profilable;
+import org.apache.avalon.excalibur.altprofile.ProfilePoint;
import org.apache.avalon.excalibur.datasource.DataSourceComponent;
import org.apache.avalon.excalibur.datasource.JdbcConnectionFactory;
import org.apache.avalon.excalibur.datasource.NoAvailableConnectionException;
@@ -131,17 +134,20 @@
* </ul>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Leif Mortenson</a>
- * @version CVS $Revision: 1.6 $ $Date: 2002/02/22 09:26:21 $
+ * @version CVS $Revision: 1.7 $ $Date: 2002/03/03 16:00:00 $
* @since 4.1
*/
public class ResourceLimitingJdbcDataSource
extends AbstractLogEnabled
- implements DataSourceComponent, Disposable
+ implements DataSourceComponent, Profilable, Disposable
{
private boolean m_configured;
private boolean m_disposed;
protected ResourceLimitingJdbcConnectionPool m_pool;
+ /** Profilable Name assigned to this Profilable */
+ private String m_profilableName;
+
/*---------------------------------------------------------------
* Constructors
*-------------------------------------------------------------*/
@@ -293,8 +299,9 @@
try
{
- m_pool = new ResourceLimitingJdbcConnectionPool
- (factory, l_max, maxStrict, blocking, timeout, trimInterval,
autoCommit );
+ m_pool = new ResourceLimitingJdbcConnectionPool(
+ factory, l_max, maxStrict, blocking, timeout, trimInterval,
autoCommit );
+
m_pool.enableLogging( getLogger() );
}
catch (Exception e)
@@ -308,6 +315,71 @@
}
m_configured = true;
+ }
+
+ /*---------------------------------------------------------------
+ * Profilable Methods
+ *-------------------------------------------------------------*/
+ /**
+ * Sets the name for the Profilable. The Profilable Name is used to
+ * uniquely identify the Profilable during the configuration of the
+ * Profiler and to gain access to a ProfilableDescriptor through a
+ * ProfilerManager. The value should be a string which does not
+ * contain spaces or periods.
+ * <p>
+ * This value may be set by a parent Profilable, or by the
ProfilerManager
+ * using the value of the 'profilable' attribute in the configuration
+ * of the component.
+ *
+ * @param name The name used to identify a Profilable.
+ */
+ public void setProfilableName( String name )
+ {
+ m_profilableName = name;
+ }
+
+ /**
+ * Gets the name of the Profilable. The Profilable Name is used to
+ * uniquely identify the Profilable during the configuration of the
+ * Profiler and to gain access to a ProfilableDescriptor through a
+ * ProfilerManager. The value should be a string which does not
+ * contain spaces or periods.
+ *
+ * @return The name used to identify a Profilable.
+ */
+ public String getProfilableName()
+ {
+ return m_profilableName;
+ }
+
+ /**
+ * Obtain a reference to all the ProfilePoints that the Profilable
+ * object wishes to expose. All sampling is done directly through
+ * the ProfilePoints as opposed to the Profilable interface.
+ *
+ * @return An array of the ProfilePoints available for profiling.
+ * Should never be null. If there are no ProfilePoints, then
+ * EMPTY_PROFILE_POINT_ARRAY can be returned. This should
+ * never be the case though unless there are child Profilables
+ * with ProfilePoints.
+ */
+ public ProfilePoint[] getProfilePoints()
+ {
+ return EMPTY_PROFILE_POINT_ARRAY;
+ }
+
+ /**
+ * Any Object which implements Profilable can also make use of other
+ * Profilable child objects. This method is used to tell the Profiler
+ * about them.
+ *
+ * @return An array of child Profilables. This method should never
+ * return null. If there are no child Profilables, then
+ * EMPTY_PROFILABLE_ARRAY can be returned.
+ */
+ public Profilable[] getChildProfilables()
+ {
+ return new Profilable[] { m_pool };
}
/*---------------------------------------------------------------
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>