You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@manifoldcf.apache.org by kw...@apache.org on 2013/02/04 20:43:48 UTC
svn commit: r1442313 - in /manifoldcf/trunk:
framework/core/src/main/java/org/apache/manifoldcf/core/database/
framework/core/src/main/java/org/apache/manifoldcf/core/jdbcpool/
framework/core/src/main/java/org/apache/manifoldcf/core/system/
site/src/do...
Author: kwright
Date: Mon Feb 4 19:43:48 2013
New Revision: 1442313
URL: http://svn.apache.org/viewvc?rev=1442313&view=rev
Log:
Change the logic so that connection tracking can be enabled by parameter.
Modified:
manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/database/ConnectionFactory.java
manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/jdbcpool/ConnectionPool.java
manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/jdbcpool/ConnectionPoolManager.java
manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/system/ManifoldCF.java
manifoldcf/trunk/site/src/documentation/content/xdocs/en_US/how-to-build-and-deploy.xml
manifoldcf/trunk/site/src/documentation/content/xdocs/ja_JP/how-to-build-and-deploy.xml
Modified: manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/database/ConnectionFactory.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/database/ConnectionFactory.java?rev=1442313&r1=1442312&r2=1442313&view=diff
==============================================================================
--- manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/database/ConnectionFactory.java (original)
+++ manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/database/ConnectionFactory.java Mon Feb 4 19:43:48 2013
@@ -179,6 +179,7 @@ public class ConnectionFactory
}
public ConnectionPoolManager createPoolManager()
+ throws ManifoldCFException
{
synchronized (poolExistenceLock)
{
Modified: manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/jdbcpool/ConnectionPool.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/jdbcpool/ConnectionPool.java?rev=1442313&r1=1442312&r2=1442313&view=diff
==============================================================================
--- manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/jdbcpool/ConnectionPool.java (original)
+++ manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/jdbcpool/ConnectionPool.java Mon Feb 4 19:43:48 2013
@@ -30,22 +30,22 @@ public class ConnectionPool
{
public static final String _rcsid = "@(#)$Id$";
- protected String dbURL;
- protected String userName;
- protected String password;
+ protected final String dbURL;
+ protected final String userName;
+ protected final String password;
protected volatile int freePointer;
protected volatile int activeConnections;
protected volatile boolean closed;
- protected Connection[] freeConnections;
- protected long[] connectionCleanupTimeouts;
- protected long expiration;
+ protected final Connection[] freeConnections;
+ protected final long[] connectionCleanupTimeouts;
+ protected final long expiration;
- protected final static boolean debug = true;
+ protected final boolean debug;
- protected List<WrappedConnection> outstandingConnections = new ArrayList<WrappedConnection>();
+ protected final Set<WrappedConnection> outstandingConnections = new HashSet<WrappedConnection>();
/** Constructor */
- public ConnectionPool(String dbURL, String userName, String password, int maxConnections, long expiration)
+ public ConnectionPool(String dbURL, String userName, String password, int maxConnections, long expiration, boolean debug)
{
this.dbURL = dbURL;
this.userName = userName;
@@ -56,6 +56,7 @@ public class ConnectionPool
this.activeConnections = 0;
this.closed = false;
this.expiration = expiration;
+ this.debug = debug;
}
/** Obtain a connection from the pool.
@@ -71,6 +72,7 @@ public class ConnectionPool
instantiationException = new Exception("Possibly leaked db connection");
else
instantiationException = null;
+ Connection rval = null;
while (true)
{
synchronized (this)
@@ -79,12 +81,9 @@ public class ConnectionPool
{
if (closed)
throw new InterruptedException("Pool already closed");
- Connection rval = freeConnections[--freePointer];
+ rval = freeConnections[--freePointer];
freeConnections[freePointer] = null;
- WrappedConnection rval3 = new WrappedConnection(this,rval,instantiationException);
- if (debug)
- outstandingConnections.add(rval3);
- return rval3;
+ break;
}
if (activeConnections == freeConnections.length)
{
@@ -92,9 +91,9 @@ public class ConnectionPool
if (debug)
{
Logging.db.warn("Out of db connections, list of outstanding ones follows.");
- for (int i = 0; i < outstandingConnections.size(); i++)
+ for (WrappedConnection c : outstandingConnections)
{
- Logging.db.warn("Found a possibly leaked db connection",outstandingConnections.get(i).getInstantiationException());
+ Logging.db.warn("Found a possibly leaked db connection",c.getInstantiationException());
}
}
// Wait until kicked; we hope something will free up...
@@ -106,30 +105,58 @@ public class ConnectionPool
break;
}
}
-
- // Create a new connection. If we fail at this we need to restore the number of active connections, so catch any failures
- Connection rval2 = null;
+
+ boolean returnedValue = true;
try
{
- if (userName != null)
- rval2 = DriverManager.getConnection(dbURL, userName, password);
- else
- rval2 = DriverManager.getConnection(dbURL);
+ if (rval == null)
+ {
+ if (userName != null)
+ rval = DriverManager.getConnection(dbURL, userName, password);
+ else
+ rval = DriverManager.getConnection(dbURL);
+ }
+
+ WrappedConnection wc = new WrappedConnection(this,rval,instantiationException);
+ if (debug)
+ {
+ synchronized (outstandingConnections)
+ {
+ outstandingConnections.add(wc);
+ }
+ }
+ return wc;
}
- finally
+ catch (Error e)
{
- if (rval2 == null)
- activeConnections--;
+ returnedValue = false;
+ throw e;
}
- WrappedConnection rval4 = new WrappedConnection(this,rval2,instantiationException);
- if (debug)
+ catch (RuntimeException e)
{
- synchronized (this)
+ returnedValue = false;
+ throw e;
+ }
+ catch (SQLException e)
+ {
+ returnedValue = false;
+ throw e;
+ }
+ finally
+ {
+ if (!returnedValue)
{
- outstandingConnections.add(rval4);
+ // We didn't finish. Restore the pool to the correct form.
+ // Note: We should always be able to just return any current connection to the pool. This is
+ // safe because we reserved a slot when we decided to create the connection (if that's what
+ // we did), or we just used a connection that was already allocated. Either way, we can put
+ // it into the pool.
+ if (rval != null)
+ {
+ release(rval);
+ }
}
}
- return rval4;
}
/** Close down the pool.
@@ -187,14 +214,30 @@ public class ConnectionPool
}
}
- public synchronized void releaseConnection(WrappedConnection connection)
+ public void releaseConnection(WrappedConnection connection)
{
- freeConnections[freePointer] = connection.getConnection();
- connectionCleanupTimeouts[freePointer] = System.currentTimeMillis() + expiration;
- freePointer++;
+
if (debug)
- outstandingConnections.remove(connection);
- notifyAll();
+ {
+ synchronized (outstandingConnections)
+ {
+ outstandingConnections.remove(connection);
+ }
+ }
+
+ release(connection.getConnection());
+ }
+
+ protected void release(Connection c)
+ {
+ synchronized (this)
+ {
+ freeConnections[freePointer] = c;
+ connectionCleanupTimeouts[freePointer] = System.currentTimeMillis() + expiration;
+ freePointer++;
+ notifyAll();
+ }
+
}
}
Modified: manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/jdbcpool/ConnectionPoolManager.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/jdbcpool/ConnectionPoolManager.java?rev=1442313&r1=1442312&r2=1442313&view=diff
==============================================================================
--- manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/jdbcpool/ConnectionPoolManager.java (original)
+++ manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/jdbcpool/ConnectionPoolManager.java Mon Feb 4 19:43:48 2013
@@ -23,18 +23,24 @@ import javax.sql.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.manifoldcf.core.interfaces.ManifoldCFException;
+import org.apache.manifoldcf.core.system.ManifoldCF;
+
/** An instance of this class manages a number of (independent) connection pools.
*/
public class ConnectionPoolManager
{
public static final String _rcsid = "@(#)$Id$";
- protected Map<String,ConnectionPool> poolMap;
- protected ConnectionCloserThread connectionCloserThread;
+ protected final Map<String,ConnectionPool> poolMap;
+ protected final ConnectionCloserThread connectionCloserThread;
protected volatile AtomicBoolean shuttingDown = new AtomicBoolean(false);
-
+ protected final boolean debug;
+
public ConnectionPoolManager(int count)
+ throws ManifoldCFException
{
+ debug = ManifoldCF.getBooleanProperty(ManifoldCF.databaseConnectionTrackingProperty, false);
poolMap = new HashMap<String,ConnectionPool>(count);
connectionCloserThread = new ConnectionCloserThread();
connectionCloserThread.start();
@@ -54,7 +60,7 @@ public class ConnectionPoolManager
throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
Class.forName(driverClassName).newInstance();
- ConnectionPool cp = new ConnectionPool(dbURL,userName,password,maxSize,expiration);
+ ConnectionPool cp = new ConnectionPool(dbURL,userName,password,maxSize,expiration,debug);
poolMap.put(poolKey,cp);
return cp;
}
Modified: manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/system/ManifoldCF.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/system/ManifoldCF.java?rev=1442313&r1=1442312&r2=1442313&view=diff
==============================================================================
--- manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/system/ManifoldCF.java (original)
+++ manifoldcf/trunk/framework/core/src/main/java/org/apache/manifoldcf/core/system/ManifoldCF.java Mon Feb 4 19:43:48 2013
@@ -109,6 +109,8 @@ public class ManifoldCF
public static final String databaseHandleMaxcountProperty = "org.apache.manifoldcf.database.maxhandles";
/** Database handle timeout property */
public static final String databaseHandleTimeoutProperty = "org.apache.manifoldcf.database.handletimeout";
+ /** Connection tracking debug property */
+ public static final String databaseConnectionTrackingProperty = "org.apache.manifoldcf.database.connectiontracking";
// Database performance monitoring properties
/** Elapsed time a query can take before a warning is output to the log, in seconds */
Modified: manifoldcf/trunk/site/src/documentation/content/xdocs/en_US/how-to-build-and-deploy.xml
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/site/src/documentation/content/xdocs/en_US/how-to-build-and-deploy.xml?rev=1442313&r1=1442312&r2=1442313&view=diff
==============================================================================
--- manifoldcf/trunk/site/src/documentation/content/xdocs/en_US/how-to-build-and-deploy.xml (original)
+++ manifoldcf/trunk/site/src/documentation/content/xdocs/en_US/how-to-build-and-deploy.xml Mon Feb 4 19:43:48 2013
@@ -801,6 +801,7 @@ cd example
<tr><td>org.apache.manifoldcf.synchdirectory</td><td>Yes, if file-based synchronization class is used</td><td>Specifies the path of a synchronization directory. All ManifoldCF process owners <strong>must</strong> have read/write privileges to this directory.</td></tr>
<tr><td>org.apache.manifoldcf.database.maxhandles</td><td>No</td><td>Specifies the maximum number of database connection handles that will by pooled. Recommended value is 200.</td></tr>
<tr><td>org.apache.manifoldcf.database.handletimeout</td><td>No</td><td>Specifies the maximum time a handle is to live before it is presumed dead. Recommend a value of 604800, which is the maximum allowable.</td></tr>
+ <tr><td>org.apache.manifoldcf.database.connectiontracking</td><td>No</td><td>True or false. When "true", will track all allocated database connection handles, and will dump an allocation stack trace when the pool is exhausted. Useful for diagnosing connection leaks.</td></tr>
<tr><td>org.apache.manifoldcf.logconfigfile</td><td>No</td><td>Specifies location of logging configuration file.</td></tr>
<tr><td>org.apache.manifoldcf.database.name</td><td>No</td><td>Describes database name for ManifoldCF; defaults to "dbname" if not specified.</td></tr>
<tr><td>org.apache.manifoldcf.database.username</td><td>No</td><td>Describes database user name for ManifoldCF; defaults to "manifoldcf" if not specified.</td></tr>
Modified: manifoldcf/trunk/site/src/documentation/content/xdocs/ja_JP/how-to-build-and-deploy.xml
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/site/src/documentation/content/xdocs/ja_JP/how-to-build-and-deploy.xml?rev=1442313&r1=1442312&r2=1442313&view=diff
==============================================================================
--- manifoldcf/trunk/site/src/documentation/content/xdocs/ja_JP/how-to-build-and-deploy.xml (original)
+++ manifoldcf/trunk/site/src/documentation/content/xdocs/ja_JP/how-to-build-and-deploy.xml Mon Feb 4 19:43:48 2013
@@ -801,6 +801,7 @@ cd example
<tr><td>org.apache.manifoldcf.synchdirectory</td><td>Yes, if file-based synchronization class is used</td><td>Specifies the path of a synchronization directory. All ManifoldCF process owners <strong>must</strong> have read/write privileges to this directory.</td></tr>
<tr><td>org.apache.manifoldcf.database.maxhandles</td><td>No</td><td>Specifies the maximum number of database connection handles that will by pooled. Recommended value is 200.</td></tr>
<tr><td>org.apache.manifoldcf.database.handletimeout</td><td>No</td><td>Specifies the maximum time a handle is to live before it is presumed dead. Recommend a value of 604800, which is the maximum allowable.</td></tr>
+ <tr><td>org.apache.manifoldcf.database.connectiontracking</td><td>No</td><td>True or false. When "true", will track all allocated database connection handles, and will dump an allocation stack trace when the pool is exhausted. Useful for diagnosing connection leaks.</td></tr>
<tr><td>org.apache.manifoldcf.logconfigfile</td><td>No</td><td>Specifies location of logging configuration file.</td></tr>
<tr><td>org.apache.manifoldcf.database.name</td><td>No</td><td>Describes database name for ManifoldCF; defaults to "dbname" if not specified.</td></tr>
<tr><td>org.apache.manifoldcf.database.username</td><td>No</td><td>Describes database user name for ManifoldCF; defaults to "manifoldcf" if not specified.</td></tr>