Index: src/java/org/apache/commons/httpclient/HttpConnectionManager.java
===================================================================
retrieving revision 1.19
diff -u -r1.19 HttpConnectionManager.java
--- src/java/org/apache/commons/httpclient/HttpConnectionManager.java 18 Apr 2004 23:51:35 -0000 1.19
+++ src/java/org/apache/commons/httpclient/HttpConnectionManager.java 19 Apr 2004 02:08:52 -0000
@@ -117,22 +117,30 @@
void releaseConnection(HttpConnection conn);
/**
+ * Closes connections that have been idle for at least the given amount of time. Only
+ * connections that are currently owned, not checked out, are subject to idle timeouts.
+ *
+ * @param idleTime the minimum idle time, in milliseconds, for connections to be closed
+ */
+ void closeIdleConnections(long idleTimeout);
+
+ /**
* Returns {@link HttpConnectionManagerParams parameters} associated
* with this connection manager.
*
- * @since 2.1
+ * @since 3.0
*
* @see HttpConnectionManagerParams
*/
- public HttpConnectionManagerParams getParams();
+ HttpConnectionManagerParams getParams();
/**
* Assigns {@link HttpConnectionManagerParams parameters} for this
* connection manager.
*
- * @since 2.1
+ * @since 3.0
*
* @see HttpConnectionManagerParams
*/
- public void setParams(final HttpConnectionManagerParams params);
+ void setParams(final HttpConnectionManagerParams params);
}
Index: src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java
===================================================================
retrieving revision 1.35
diff -u -r1.35 MultiThreadedHttpConnectionManager.java
--- src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java 18 Apr 2004 23:51:35 -0000 1.35
+++ src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java 19 Apr 2004 02:08:56 -0000
@@ -47,6 +47,7 @@
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.Protocol;
+import org.apache.commons.httpclient.util.IdleConnectionHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -547,6 +548,13 @@
}
}
+ /* (non-Javadoc)
+ * @see org.apache.commons.httpclient.HttpConnectionManager#closeIdleConnections(long)
+ */
+ public void closeIdleConnections(long idleTimeout) {
+ connectionPool.closeIdleConnections(idleTimeout);
+ }
+
/**
* Make the given HttpConnection available for use by other requests.
* If another thread is blocked in getConnection() that could use this
@@ -640,6 +648,8 @@
*/
private final Map mapHosts = new HashMap();
+ private IdleConnectionHandler idleConnectionHandler = new IdleConnectionHandler();
+
/** The number of created connections */
private int numConnections = 0;
@@ -669,6 +679,9 @@
// clear out map hosts
mapHosts.clear();
+
+ // remove all references to connections
+ idleConnectionHandler.removeAll();
}
/**
@@ -770,6 +783,9 @@
if (LOG.isDebugEnabled()) {
LOG.debug("Getting free connection, hostConfig=" + hostConfiguration);
}
+
+ // remove the connection from the timeout handler
+ idleConnectionHandler.remove(connection);
} else if (LOG.isDebugEnabled()) {
LOG.debug("There were no free connections to get, hostConfig="
+ hostConfiguration);
@@ -778,6 +794,14 @@
}
/**
+ * Closes idle connections.
+ * @param idleTimeout
+ */
+ public synchronized void closeIdleConnections(long idleTimeout) {
+ idleConnectionHandler.closeIdleConnections(idleTimeout);
+ }
+
+ /**
* Close and delete an old, unused connection to make room for a new one.
*/
public synchronized void deleteLeastUsedConnection() {
@@ -799,6 +823,10 @@
hostPool.freeConnections.remove(connection);
hostPool.numConnections--;
numConnections--;
+
+ // remove the connection from the timeout handler
+ idleConnectionHandler.remove(connection);
+
} else if (LOG.isDebugEnabled()) {
LOG.debug("Attempted to reclaim an unused connection but there were none.");
}
@@ -892,7 +920,10 @@
+ connectionConfiguration);
numConnections = 1;
}
-
+
+ // register the connection with the timeout handler
+ idleConnectionHandler.add(conn);
+
notifyWaitingThread(hostPool);
}
}
Index: src/java/org/apache/commons/httpclient/ProxyClient.java
===================================================================
retrieving revision 1.2
diff -u -r1.2 ProxyClient.java
--- src/java/org/apache/commons/httpclient/ProxyClient.java 18 Apr 2004 23:51:35 -0000 1.2
+++ src/java/org/apache/commons/httpclient/ProxyClient.java 19 Apr 2004 02:08:57 -0000
@@ -267,6 +267,9 @@
private HttpParams connectionParams;
+ public void closeIdleConnections(long idleTimeout) {
+ }
+
public HttpConnection getConnection() {
return httpConnection;
}
Index: src/java/org/apache/commons/httpclient/SimpleHttpConnectionManager.java
===================================================================
retrieving revision 1.18
diff -u -r1.18 SimpleHttpConnectionManager.java
--- src/java/org/apache/commons/httpclient/SimpleHttpConnectionManager.java 18 Apr 2004 23:51:35 -0000 1.18
+++ src/java/org/apache/commons/httpclient/SimpleHttpConnectionManager.java 19 Apr 2004 02:08:57 -0000
@@ -33,6 +33,7 @@
import java.io.InputStream;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
+import org.apache.commons.httpclient.util.IdleConnectionHandler;
/**
* A connection manager that provides access to a single HttpConnection. This
@@ -57,6 +58,11 @@
*/
private HttpConnectionManagerParams params = new HttpConnectionManagerParams();
+ private IdleConnectionHandler idleConnectionHandler = new IdleConnectionHandler();
+
+ public SimpleHttpConnectionManager() {
+ }
+
/**
* @see HttpConnectionManager#getConnection(HostConfiguration)
*/
@@ -127,6 +133,9 @@
}
}
+ // remove the connection from the timeout handler
+ idleConnectionHandler.remove(httpConnection);
+
return httpConnection;
}
@@ -149,6 +158,9 @@
}
finishLastResponse(httpConnection);
+
+ // register the connection with the timeout handler
+ idleConnectionHandler.add(httpConnection);
}
/**
@@ -195,5 +207,12 @@
throw new IllegalArgumentException("Parameters may not be null");
}
this.params = params;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.httpclient.HttpConnectionManager#closeIdleConnections(long)
+ */
+ public void closeIdleConnections(long idleTimeout) {
+ idleConnectionHandler.closeIdleConnections(idleTimeout);
}
}
Index: src/test/org/apache/commons/httpclient/NoHostHttpConnectionManager.java
===================================================================
retrieving revision 1.5
diff -u -r1.5 NoHostHttpConnectionManager.java
--- src/test/org/apache/commons/httpclient/NoHostHttpConnectionManager.java 22 Feb 2004 18:08:49 -0000 1.5
+++ src/test/org/apache/commons/httpclient/NoHostHttpConnectionManager.java 19 Apr 2004 02:08:58 -0000
@@ -45,9 +45,15 @@
private boolean connectionReleased = false;
private HttpConnectionManagerParams params = new HttpConnectionManagerParams();
-
+
public NoHostHttpConnectionManager() {
setConnection(new SimpleHttpConnection());
+ }
+
+ /**
+ * This method currently does nothing.
+ */
+ public void closeIdleConnections(long idleTimeout) {
}
/**
Index: src/test/org/apache/commons/httpclient/TestNoHost.java
===================================================================
retrieving revision 1.34
diff -u -r1.34 TestNoHost.java
--- src/test/org/apache/commons/httpclient/TestNoHost.java 12 Apr 2004 10:30:46 -0000 1.34
+++ src/test/org/apache/commons/httpclient/TestNoHost.java 19 Apr 2004 02:08:58 -0000
@@ -86,6 +86,7 @@
suite.addTest(TestHttpParser.suite());
suite.addTest(TestBadContentLength.suite());
suite.addTest(TestEquals.suite());
+ suite.addTestSuite(TestIdleConnectionQueue.class);
return suite;
}
Index: src/java/org/apache/commons/httpclient/util/IdleConnectionHandler.java
===================================================================
RCS file: src/java/org/apache/commons/httpclient/util/IdleConnectionHandler.java
diff -N src/java/org/apache/commons/httpclient/util/IdleConnectionHandler.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/java/org/apache/commons/httpclient/util/IdleConnectionHandler.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,152 @@
+/*
+ * $Header: $
+ * $Revision: $
+ * $Date: $
+ *
+ * ====================================================================
+ *
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ *
This class is not synchronized.
+ * + * @see org.apache.commons.httpclient.HttpConnectionManager#closeIdleConnections(long) + */ +public class IdleConnectionHandler { + + private static final Log LOG = LogFactory.getLog(IdleConnectionHandler.class); + + // holds connections to be tracked + private HashSet connections = new HashSet(); + + // holds connections ordered by the timeout they were added + private TreeMap timeAddedToConnection = new TreeMap(); + + private Thread timeoutThread; + + /** + * + */ + public IdleConnectionHandler() { + super(); + } + + /** + * Registers the given connection with this handler. The connection will be held until + * {@link #remove(HttpConnection)} or {@link #closeIdleConnections(long)} is called. + * + * @param connection the connection to add + * + * @see #remove(HttpConnection) + */ + public void add(HttpConnection connection) { + + Long timeAdded = new Long(System.currentTimeMillis()); + + if (LOG.isDebugEnabled()) { + LOG.debug("Adding connection at: " + timeAdded); + } + + List tempList = (List) timeAddedToConnection.get(timeAdded); + if (tempList == null) { + tempList = new ArrayList(); + timeAddedToConnection.put(timeAdded, tempList); + } + tempList.add(connection); + connections.add(connection); + } + + /** + * Removes the given connection from the list of connections to be closed when idle. + * @param connection + */ + public void remove(HttpConnection connection) { + // TODO what about connections that are removed, and then readded before + // the original timeout has occurred? + connections.remove(connection); + } + + /** + * Removes all connections referenced by this handler. + */ + public void removeAll() { + this.connections.clear(); + this.timeAddedToConnection.clear(); + } + + /** + * Closes connections that have been idle for at least the given amount of time. + * + * @param idleTime the minimum idle time, in milliseconds, for connections to be closed + */ + public void closeIdleConnections(long idleTime) { + + // the latest time for which connections will be closed + long idleTimeout = System.currentTimeMillis() - idleTime; + + if (LOG.isDebugEnabled()) { + LOG.debug("Checking for connections, idleTimeout: " + idleTimeout); + } + + Iterator timeoutIter = timeAddedToConnection.keySet().iterator(); + + while (timeoutIter.hasNext()) { + Long connectionTime = (Long) timeoutIter.next(); + if (connectionTime.longValue() <= idleTimeout) { + if (LOG.isDebugEnabled()) { + LOG.debug("Connections timed out, connection time: " + connectionTime); + } + List tempList = (List) timeAddedToConnection.get(connectionTime); + Iterator connectionIter = tempList.iterator(); + while (connectionIter.hasNext()) { + HttpConnection conn = (HttpConnection) connectionIter.next(); + // only close this connection if it has not been removed + if (connections.remove(conn)) { + LOG.debug("Closing connection"); + conn.close(); + } else { + LOG.debug("NOT closing connection"); + } + } + timeoutIter.remove(); + } else { + break; + } + } + } +} Index: src/test/org/apache/commons/httpclient/TestIdleConnectionQueue.java =================================================================== RCS file: src/test/org/apache/commons/httpclient/TestIdleConnectionQueue.java diff -N src/test/org/apache/commons/httpclient/TestIdleConnectionQueue.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/test/org/apache/commons/httpclient/TestIdleConnectionQueue.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,120 @@ +/* + * $Header: $ + * $Revision: $ + * $Date: $ + * + * ==================================================================== + * + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + *