Index: src/java/org/apache/commons/httpclient/HttpConnection.java
===================================================================
retrieving revision 1.92
diff -u -r1.92 HttpConnection.java
--- src/java/org/apache/commons/httpclient/HttpConnection.java 1 Jun 2004 00:55:10 -0000 1.92
+++ src/java/org/apache/commons/httpclient/HttpConnection.java 5 Jun 2004 01:50:28 -0000
@@ -383,19 +383,51 @@
}
/**
- * Returns true if the connection is open,
- * false otherwise.
+ * Tests if the connection is open. When {@link HttpConnectionParams#isStaleCheckingEnabled()
+ * stale checking is enabled} this method will also call {@link #closeIfStale()} which
+ * may result in the connection being closed.
*
- * @return true if the connection is open
+ * @return true if the connection is open
*/
public boolean isOpen() {
- if (used && isOpen && this.params.isStaleCheckingEnabled() && isStale()) {
- LOG.debug("Connection is stale, closing...");
- close();
+ if (this.params.isStaleCheckingEnabled()) {
+ closeIfStale();
}
return isOpen;
}
+ /**
+ * Closes the connection if stale.
+ *
+ * @return true if the connection was stale and therefore closed,
+ * false otherwise.
+ *
+ * @see #isStale()
+ */
+ public boolean closeIfStale() {
+ if (used && isOpen && isStale()) {
+ LOG.debug("Connection is stale, closing...");
+ close();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Tests if this connections has been closed. This will only be true if
+ * {@link #close()} has been called or if {@link #closeIfStale()} was called on
+ * a stale connection.
+ *
+ *
Note that isClosed() may not be equal to !isOpen().
+ * This is because isOpen() will call closeIfStale() when
+ * {@link HttpConnectionParams#isStaleCheckingEnabled() stale checking is enabled}.
true if this connection is closed.
+ */
+ public boolean isClosed() {
+ return !isOpen;
+ }
+
/**
* Tests if stale checking is enabled.
*
Index: src/java/org/apache/commons/httpclient/HttpMethodDirector.java
===================================================================
retrieving revision 1.25
diff -u -r1.25 HttpMethodDirector.java
--- src/java/org/apache/commons/httpclient/HttpMethodDirector.java 13 May 2004 04:03:25 -0000 1.25
+++ src/java/org/apache/commons/httpclient/HttpMethodDirector.java 5 Jun 2004 01:50:30 -0000
@@ -395,14 +395,14 @@
}
}
} catch (IOException e) {
- if (this.conn.isOpen()) {
+ if (!this.conn.isClosed()) {
LOG.debug("Closing the connection.");
this.conn.close();
}
releaseConnection = true;
throw e;
} catch (RuntimeException e) {
- if (this.conn.isOpen()) {
+ if (!this.conn.isClosed()) {
LOG.debug("Closing the connection.");
this.conn.close();
}
Index: src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java
===================================================================
retrieving revision 1.39
diff -u -r1.39 MultiThreadedHttpConnectionManager.java
--- src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java 13 May 2004 04:03:25 -0000 1.39
+++ src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java 5 Jun 2004 01:50:34 -0000
@@ -527,30 +527,72 @@
}
/**
+ * Gets the total number of pooled connections for the given host configuration. This
+ * is the total number of connections that have been created and are still in use
+ * by this connection manager for the host configuration. This value will
+ * not exceed the {@link #getMaxConnectionsPerHost() maximum number of connections per
+ * host}.
+ *
+ * @param hostConfiguration The host configuration
+ * @return The total number of pooled connections
+ */
+ public int getConnectionsInPool(HostConfiguration hostConfiguration) {
+ synchronized (connectionPool) {
+ HostConnectionPool hostPool = connectionPool.getHostPool(hostConfiguration);
+ return hostPool.numConnections;
+ }
+ }
+
+ /**
+ * Gets the total number of pooled connections. This is the total number of
+ * connections that have been created and are still in use by this connection
+ * manager. This value will not exceed the {@link #getMaxTotalConnections()
+ * maximum number of connections}.
+ *
+ * @return the total number of pooled connections
+ */
+ public int getConnectionsInPool() {
+ synchronized (connectionPool) {
+ return connectionPool.numConnections;
+ }
+ }
+
+ /**
* Gets the number of connections in use for this configuration.
*
* @param hostConfiguration the key that connections are tracked on
* @return the number of connections in use
+ *
+ * @deprecated Use {@link #getConnectionsInPool(HostConfiguration)}
*/
public int getConnectionsInUse(HostConfiguration hostConfiguration) {
- synchronized (connectionPool) {
- HostConnectionPool hostPool = connectionPool.getHostPool(hostConfiguration);
- return hostPool.numConnections;
- }
+ return getConnectionsInPool(hostConfiguration);
}
/**
* Gets the total number of connections in use.
*
* @return the total number of connections in use
+ *
+ * @deprecated Use {@link #getConnectionsInPool()}
*/
public int getConnectionsInUse() {
- synchronized (connectionPool) {
- return connectionPool.numConnections;
- }
+ return getConnectionsInPool();
}
/**
+ * Deletes all closed connections. Only connections currently owned by the connection
+ * manager are processed.
+ *
+ * @see HttpConnection#isClosed()
+ *
+ * @since 3.0
+ */
+ public void deleteClosedConnections() {
+ connectionPool.deleteClosedConnections();
+ }
+
+ /**
* @since 3.0
*/
public void closeIdleConnections(long idleTimeout) {
@@ -794,6 +836,22 @@
}
return connection;
}
+
+ /**
+ * Deletes all closed connections.
+ */
+ public synchronized void deleteClosedConnections() {
+
+ Iterator iter = freeConnections.iterator();
+
+ while (iter.hasNext()) {
+ HttpConnection conn = (HttpConnection) iter.next();
+ if (conn.isClosed()) {
+ iter.remove();
+ deleteConnection(conn);
+ }
+ }
+ }
/**
* Closes idle connections.
@@ -804,31 +862,43 @@
}
/**
- * Close and delete an old, unused connection to make room for a new one.
+ * Deletes the given connection. This will remove all reference to the connection
+ * so that it can be GCed.
+ *
+ * Note: Does not remove the connection from the freeConnections list. It + * is assumed that the caller has already handled this case.
+ * + * @param connection The connection to delete */ - public synchronized void deleteLeastUsedConnection() { + private synchronized void deleteConnection(HttpConnection connection) { + + HostConfiguration connectionConfiguration = configurationForConnection(connection); - HttpConnection connection = (HttpConnection) freeConnections.removeFirst(); + if (LOG.isDebugEnabled()) { + LOG.debug("Reclaiming connection, hostConfig=" + connectionConfiguration); + } - if (connection != null) { - HostConfiguration connectionConfiguration = configurationForConnection(connection); + connection.close(); - if (LOG.isDebugEnabled()) { - LOG.debug("Reclaiming unused connection, hostConfig=" - + connectionConfiguration); - } + HostConnectionPool hostPool = getHostPool(connectionConfiguration); + + hostPool.freeConnections.remove(connection); + hostPool.numConnections--; + numConnections--; - connection.close(); + // remove the connection from the timeout handler + idleConnectionHandler.remove(connection); + } + + /** + * Close and delete an old, unused connection to make room for a new one. + */ + public synchronized void deleteLeastUsedConnection() { - HostConnectionPool hostPool = getHostPool(connectionConfiguration); - - hostPool.freeConnections.remove(connection); - hostPool.numConnections--; - numConnections--; + HttpConnection connection = (HttpConnection) freeConnections.removeFirst(); - // remove the connection from the timeout handler - idleConnectionHandler.remove(connection); - + if (connection != null) { + deleteConnection(connection); } else if (LOG.isDebugEnabled()) { LOG.debug("Attempted to reclaim an unused connection but there were none."); } @@ -1217,6 +1287,22 @@ } } + public boolean closeIfStale() { + if (hasConnection()) { + return wrappedConnection.closeIfStale(); + } else { + return false; + } + } + + public boolean isClosed() { + if (hasConnection()) { + return wrappedConnection.isClosed(); + } else { + return true; + } + } + public boolean isProxied() { if (hasConnection()) { return wrappedConnection.isProxied(); Index: src/test/org/apache/commons/httpclient/TestHttpConnection.java =================================================================== retrieving revision 1.16 diff -u -r1.16 TestHttpConnection.java --- src/test/org/apache/commons/httpclient/TestHttpConnection.java 13 Apr 2004 21:47:29 -0000 1.16 +++ src/test/org/apache/commons/httpclient/TestHttpConnection.java 5 Jun 2004 01:50:35 -0000 @@ -80,7 +80,8 @@ public void testConstructThenClose() { HttpConnection conn = new HttpConnection(getHost(), getPort()); conn.close(); - assertTrue( ! conn.isOpen() ); + assertTrue(!conn.isOpen()); + assertTrue(conn.isClosed()); } public void testConnTimeoutRelease() { Index: src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java =================================================================== retrieving revision 1.21 diff -u -r1.21 TestHttpConnectionManager.java --- src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java 13 Apr 2004 21:47:29 -0000 1.21 +++ src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java 5 Jun 2004 01:50:37 -0000 @@ -583,6 +583,31 @@ } + public void testDeleteClosedConnections() { + + MultiThreadedHttpConnectionManager manager = new MultiThreadedHttpConnectionManager(); + + HostConfiguration hostConfig = new HostConfiguration(); + + configureHostConfiguration(hostConfig); + + HttpConnection conn = manager.getConnection(hostConfig); + + assertEquals("connectionsInPool", manager.getConnectionsInPool(), 1); + assertEquals("connectionsInPool(host)", manager.getConnectionsInPool(hostConfig), 1); + + conn.close(); + conn.releaseConnection(); + + assertEquals("connectionsInPool", manager.getConnectionsInPool(), 1); + assertEquals("connectionsInPool(host)", manager.getConnectionsInPool(hostConfig), 1); + + manager.deleteClosedConnections(); + + assertEquals("connectionsInPool", manager.getConnectionsInPool(), 0); + assertEquals("connectionsInPool(host)", manager.getConnectionsInPool(hostConfig), 0); + } + public void testReclaimUnusedConnection() { MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); Index: src/test/org/apache/commons/httpclient/TestLocalHostBase.java =================================================================== retrieving revision 1.5 diff -u -r1.5 TestLocalHostBase.java --- src/test/org/apache/commons/httpclient/TestLocalHostBase.java 22 Feb 2004 18:08:49 -0000 1.5 +++ src/test/org/apache/commons/httpclient/TestLocalHostBase.java 5 Jun 2004 01:50:37 -0000 @@ -99,13 +99,22 @@ } else { client = new HttpClient(connectionManager); } - - client.getHostConfiguration().setHost(host, port, protocol); - if (proxyHost != null) { - client.getHostConfiguration().setProxy(proxyHost, proxyPort); - } + + configureHostConfiguration(client.getHostConfiguration()); return client; + } + + /** + * Configures the host config with the correct host and proxy settings. + * + * @param hostConfiguration + */ + public void configureHostConfiguration(HostConfiguration hostConfiguration) { + hostConfiguration.setHost(host, port, protocol); + if (proxyHost != null) { + hostConfiguration.setProxy(proxyHost, proxyPort); + } } /**