mbecke 2004/06/24 20:34:56 Modified: httpclient/src/java/org/apache/commons/httpclient HttpMethodDirector.java MultiThreadedHttpConnectionManager.java HttpConnection.java httpclient/src/test/org/apache/commons/httpclient TestLocalHostBase.java TestHttpConnection.java TestHttpConnectionManager.java Log: Adds MultiThreadedHttpConnectionManager.deleteClosedConnections() and HttpConnection.closeIfStale(). PR: 29383 Submitted by: Michael Becke and Oleg Kalnichevski Reviewed by: Oleg Kalnichevski, Michael Becke and Roland Weber Revision Changes Path 1.27 +7 -4 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodDirector.java Index: HttpMethodDirector.java =================================================================== RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodDirector.java,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- HttpMethodDirector.java 12 Jun 2004 22:47:23 -0000 1.26 +++ HttpMethodDirector.java 25 Jun 2004 03:34:56 -0000 1.27 @@ -351,6 +351,9 @@ if (LOG.isTraceEnabled()) { LOG.trace("Attempt number " + execCount + " to process request"); } + if (this.conn.getParams().isStaleCheckingEnabled()) { + this.conn.closeIfStale(); + } if (!this.conn.isOpen()) { // this connection must be opened before it can be used // This has nothing to do with opening a secure tunnel @@ -414,7 +417,7 @@ releaseConnection = true; throw e; } catch (RuntimeException e) { - if (this.conn.isOpen()) { + if (this.conn.isOpen) { LOG.debug("Closing the connection."); this.conn.close(); } 1.40 +106 -28 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java Index: MultiThreadedHttpConnectionManager.java =================================================================== RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java,v retrieving revision 1.39 retrieving revision 1.40 diff -u -r1.39 -r1.40 --- MultiThreadedHttpConnectionManager.java 13 May 2004 04:03:25 -0000 1.39 +++ MultiThreadedHttpConnectionManager.java 25 Jun 2004 03:34:56 -0000 1.40 @@ -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 [EMAIL PROTECTED] #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 [EMAIL PROTECTED] #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 [EMAIL PROTECTED] #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 [EMAIL PROTECTED] #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.isOpen()) { + 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. + * + * <p><b>Note:</b> Does not remove the connection from the freeConnections list. It + * is assumed that the caller has already handled this case.</p> + * + * @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."); } @@ -1212,6 +1282,14 @@ public boolean isOpen() { if (hasConnection()) { return wrappedConnection.isOpen(); + } else { + return false; + } + } + + public boolean closeIfStale() { + if (hasConnection()) { + return wrappedConnection.closeIfStale(); } else { return false; } 1.95 +22 -10 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java Index: HttpConnection.java =================================================================== RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java,v retrieving revision 1.94 retrieving revision 1.95 diff -u -r1.94 -r1.95 --- HttpConnection.java 24 Jun 2004 21:39:52 -0000 1.94 +++ HttpConnection.java 25 Jun 2004 03:34:56 -0000 1.95 @@ -383,19 +383,31 @@ } /** - * Returns <tt>true</tt> if the connection is open, - * <tt>false</tt> otherwise. + * Tests if the connection is open. * - * @return <tt>true</tt> if the connection is open + * @return <code>true</code> if the connection is open */ public boolean isOpen() { - if (used && isOpen && this.params.isStaleCheckingEnabled() && isStale()) { + return isOpen; + } + + /** + * Closes the connection if stale. + * + * @return <code>true</code> if the connection was stale and therefore closed, + * <code>false</code> otherwise. + * + * @see #isStale() + */ + public boolean closeIfStale() { + if (used && isOpen && isStale()) { LOG.debug("Connection is stale, closing..."); close(); + return true; } - return isOpen; + return false; } - + /** * Tests if stale checking is enabled. * 1.6 +17 -8 jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestLocalHostBase.java Index: TestLocalHostBase.java =================================================================== RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestLocalHostBase.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- TestLocalHostBase.java 22 Feb 2004 18:08:49 -0000 1.5 +++ TestLocalHostBase.java 25 Jun 2004 03:34:56 -0000 1.6 @@ -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); + } } /** 1.17 +1 -1 jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnection.java Index: TestHttpConnection.java =================================================================== RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnection.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- TestHttpConnection.java 13 Apr 2004 21:47:29 -0000 1.16 +++ TestHttpConnection.java 25 Jun 2004 03:34:56 -0000 1.17 @@ -80,7 +80,7 @@ public void testConstructThenClose() { HttpConnection conn = new HttpConnection(getHost(), getPort()); conn.close(); - assertTrue( ! conn.isOpen() ); + assertTrue(!conn.isOpen()); } public void testConnTimeoutRelease() { 1.22 +29 -4 jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java Index: TestHttpConnectionManager.java =================================================================== RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java,v retrieving revision 1.21 retrieving revision 1.22 diff -u -r1.21 -r1.22 --- TestHttpConnectionManager.java 13 Apr 2004 21:47:29 -0000 1.21 +++ TestHttpConnectionManager.java 25 Jun 2004 03:34:56 -0000 1.22 @@ -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();
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]