mbecke 2003/07/30 19:31:09 Modified: httpclient/src/java/org/apache/commons/httpclient Tag: HTTPCLIENT_2_0_BRANCH SimpleHttpConnectionManager.java MultiThreadedHttpConnectionManager.java HttpConnection.java HostConfiguration.java Log: Added support for disabling HttpConnection.isStale() as well as more connection logging in MultiThreadedHttpConnectionManager. Submitted by: Michael Becke Reviewed by: Oleg Kalnichevski Revision Changes Path No revision No revision 1.12.2.1 +32 -4 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/SimpleHttpConnectionManager.java Index: SimpleHttpConnectionManager.java =================================================================== RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/SimpleHttpConnectionManager.java,v retrieving revision 1.12 retrieving revision 1.12.2.1 diff -u -r1.12 -r1.12.2.1 --- SimpleHttpConnectionManager.java 12 May 2003 02:42:42 -0000 1.12 +++ SimpleHttpConnectionManager.java 31 Jul 2003 02:31:09 -0000 1.12.2.1 @@ -84,6 +84,9 @@ /** The http connection */ private HttpConnection httpConnection; + /** The value to set when calling setStaleCheckingEnabled() on connections */ + private boolean connectionStaleCheckingEnabled = true; + /** * Constructor for SimpleHttpConnectionManager. */ @@ -99,6 +102,29 @@ } /** + * Gets the staleCheckingEnabled value to be set on HttpConnections that are created. + * + * @return <code>true</code> if stale checking will be enabled on HttpConections + * + * @see HttpConnection#isStaleCheckingEnabled() + */ + public boolean isConnectionStaleCheckingEnabled() { + return connectionStaleCheckingEnabled; + } + + /** + * Sets the staleCheckingEnabled value to be set on HttpConnections that are created. + * + * @param connectionStaleCheckingEnabled <code>true</code> if stale checking will be enabled + * on HttpConections + * + * @see HttpConnection#setStaleCheckingEnabled(boolean) + */ + public void setConnectionStaleCheckingEnabled(boolean connectionStaleCheckingEnabled) { + this.connectionStaleCheckingEnabled = connectionStaleCheckingEnabled; + } + + /** * @see HttpConnectionManager#getConnection(HostConfiguration, long) */ public HttpConnection getConnection( @@ -106,6 +132,7 @@ if (httpConnection == null) { httpConnection = new HttpConnection(hostConfiguration); + httpConnection.setStaleCheckingEnabled(connectionStaleCheckingEnabled); } else { // make sure the host and proxy are correct for this connection @@ -117,6 +144,8 @@ httpConnection.close(); } + httpConnection.setStaleCheckingEnabled(connectionStaleCheckingEnabled); + httpConnection.setHost(hostConfiguration.getHost()); httpConnection.setVirtualHost(hostConfiguration.getVirtualHost()); httpConnection.setPort(hostConfiguration.getPort()); @@ -131,7 +160,6 @@ } return httpConnection; - } /** 1.17.2.2 +101 -18 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.17.2.1 retrieving revision 1.17.2.2 diff -u -r1.17.2.1 -r1.17.2.2 --- MultiThreadedHttpConnectionManager.java 23 Jul 2003 01:47:20 -0000 1.17.2.1 +++ MultiThreadedHttpConnectionManager.java 31 Jul 2003 02:31:09 -0000 1.17.2.2 @@ -69,6 +69,7 @@ import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; +import java.net.InetAddress; import java.net.SocketException; import java.util.Collections; import java.util.HashMap; @@ -109,6 +110,9 @@ /** Maximum number of connections allowed overall */ private int maxTotalConnections = DEFAULT_MAX_TOTAL_CONNECTIONS; + /** The value to set when calling setStaleCheckingEnabled() on each connection */ + private boolean connectionStaleCheckingEnabled = true; + /** Connection Pool */ private ConnectionPool connectionPool; @@ -132,7 +136,29 @@ this.referenceQueue = new ReferenceQueue(); new ReferenceQueueThread().start(); + } + /** + * Gets the staleCheckingEnabled value to be set on HttpConnections that are created. + * + * @return <code>true</code> if stale checking will be enabled on HttpConections + * + * @see HttpConnection#isStaleCheckingEnabled() + */ + public boolean isConnectionStaleCheckingEnabled() { + return connectionStaleCheckingEnabled; + } + + /** + * Sets the staleCheckingEnabled value to be set on HttpConnections that are created. + * + * @param connectionStaleCheckingEnabled <code>true</code> if stale checking will be enabled + * on HttpConections + * + * @see HttpConnection#setStaleCheckingEnabled(boolean) + */ + public void setConnectionStaleCheckingEnabled(boolean connectionStaleCheckingEnabled) { + this.connectionStaleCheckingEnabled = connectionStaleCheckingEnabled; } /** @@ -279,7 +305,7 @@ // become true // } else { - // todo: keep track of which hostConfigurations have waiting + // TODO: keep track of which hostConfigurations have waiting // threads, so they avoid being sacrificed before necessary try { @@ -289,7 +315,7 @@ } if (LOG.isDebugEnabled()) { - LOG.debug("Waiting for a connection "); + LOG.debug("Unable to get a connection, waiting..., hostConfig=" + hostConfiguration); } if (waitingThread == null) { @@ -307,9 +333,9 @@ connectionPool.wait(timeToWait); // we have not been interrupted so we need to remove ourselves from the - // wait queue - hostPool.waitingThreads.remove(waitingThread); - connectionPool.waitingThreads.remove(waitingThread); + // wait queue + hostPool.waitingThreads.remove(waitingThread); + connectionPool.waitingThreads.remove(waitingThread); } catch (InterruptedException e) { // do nothing } finally { @@ -380,11 +406,16 @@ private HostConfiguration configurationForConnection(HttpConnection conn) { HostConfiguration connectionConfiguration = new HostConfiguration(); + connectionConfiguration.setHost( conn.getHost(), conn.getVirtualHost(), conn.getPort(), - conn.getProtocol()); + conn.getProtocol() + ); + if (conn.getLocalAddress() != null) { + connectionConfiguration.setLocalAddress(conn.getLocalAddress()); + } if (conn.getProxyHost() != null) { connectionConfiguration.setProxy(conn.getProxyHost(), conn.getProxyPort()); } @@ -428,9 +459,10 @@ && (numConnections < getMaxTotalConnections())) { if (LOG.isDebugEnabled()) { - LOG.debug("Allocating new connection for hostConfig: " + hostConfiguration); + LOG.debug("Allocating new connection, hostConfig=" + hostConfiguration); } connection = new HttpConnection(hostConfiguration); + connection.setStaleCheckingEnabled(connectionStaleCheckingEnabled); connection.setHttpConnectionManager(MultiThreadedHttpConnectionManager.this); numConnections++; hostPool.numConnections++; @@ -438,7 +470,17 @@ // add a weak reference to this connection referenceToHostConfig.put(new WeakReference(connection, referenceQueue), hostConfiguration); + } else if (LOG.isDebugEnabled()) { + if (hostPool.numConnections >= getMaxConnectionsPerHost()) { + LOG.debug("No connection allocated, host pool has already reached " + + "maxConnectionsPerHost, hostConfig=" + hostConfiguration + + ", maxConnectionsPerhost=" + getMaxConnectionsPerHost()); + } else { + LOG.debug("No connection allocated, maxTotalConnections reached, " + + "maxTotalConnections=" + getMaxTotalConnections()); + } } + return connection; } @@ -457,6 +499,7 @@ if (listConnections == null) { // First time for this config listConnections = new HostConnectionPool(); + listConnections.hostConfiguration = hostConfiguration; mapHosts.put(hostConfiguration, listConnections); } @@ -479,8 +522,11 @@ connection = (HttpConnection) hostPool.freeConnections.removeFirst(); freeConnections.remove(connection); if (LOG.isDebugEnabled()) { - LOG.debug("Getting connection for hostConfig: " + hostConfiguration); + LOG.debug("Getting free connection, hostConfig=" + hostConfiguration); } + } else if (LOG.isDebugEnabled()) { + LOG.debug("There were no free connections to get, hostConfig=" + + hostConfiguration); } return connection; } @@ -496,7 +542,7 @@ HostConfiguration connectionConfiguration = configurationForConnection(connection); if (LOG.isDebugEnabled()) { - LOG.debug("Reclaiming unused connection for hostConfig: " + LOG.debug("Reclaiming unused connection, hostConfig=" + connectionConfiguration); } @@ -518,6 +564,8 @@ hostPool.freeConnections.remove(connection); hostPool.numConnections--; numConnections--; + } else if (LOG.isDebugEnabled()) { + LOG.debug("Attempted to reclaim an unused connection but there were none."); } } @@ -547,13 +595,14 @@ if (hostPool.waitingThreads.size() > 0) { if (LOG.isDebugEnabled()) { - LOG.debug("Notifying thread waiting on hostPool"); + LOG.debug("Notifying thread waiting on host pool, hostConfig=" + + hostPool.hostConfiguration); } waitingThread = (WaitingThread) hostPool.waitingThreads.removeFirst(); waitingThreads.remove(waitingThread); } else if (waitingThreads.size() > 0) { if (LOG.isDebugEnabled()) { - LOG.debug("Notifying next waiting thread"); + LOG.debug("No-one waiting on host pool, notifying next waiting thread."); } waitingThread = (WaitingThread) waitingThreads.removeFirst(); waitingThread.hostConnectionPool.waitingThreads.remove(waitingThread); @@ -575,7 +624,7 @@ HostConfiguration connectionConfiguration = configurationForConnection(conn); if (LOG.isDebugEnabled()) { - LOG.debug("Freeing connection for hostConfig: " + connectionConfiguration); + LOG.debug("Freeing connection, hostConfig=" + connectionConfiguration); } synchronized (this) { @@ -585,7 +634,7 @@ hostPool.freeConnections.add(conn); if (hostPool.numConnections == 0) { // for some reason this connection pool didn't already exist - LOG.error("host connection pool not found for: " + LOG.error("Host connection pool not found, hostConfig=" + connectionConfiguration); hostPool.numConnections = 1; } @@ -593,14 +642,13 @@ freeConnections.add(conn); if (numConnections == 0) { // for some reason this connection pool didn't already exist - LOG.error("connection pool not found for: " + LOG.error("Host connection pool not found, hostConfig=" + connectionConfiguration); numConnections = 1; } notifyWaitingThread(hostPool); } - } } @@ -609,6 +657,9 @@ * of created connections. */ private class HostConnectionPool { + /** The hostConfig this pool is for */ + public HostConfiguration hostConfiguration; + /** The list of free connections */ public LinkedList freeConnections = new LinkedList(); @@ -723,6 +774,38 @@ wrappedConnection.close(); } else { // do nothing + } + } + + public InetAddress getLocalAddress() { + if (hasConnection()) { + return wrappedConnection.getLocalAddress(); + } else { + return null; + } + } + + public boolean isStaleCheckingEnabled() { + if (hasConnection()) { + return wrappedConnection.isStaleCheckingEnabled(); + } else { + return false; + } + } + + public void setLocalAddress(InetAddress localAddress) { + if (hasConnection()) { + wrappedConnection.setLocalAddress(localAddress); + } else { + throw new IllegalStateException("Connection has been released"); + } + } + + public void setStaleCheckingEnabled(boolean staleCheckEnabled) { + if (hasConnection()) { + wrappedConnection.setStaleCheckingEnabled(staleCheckEnabled); + } else { + throw new IllegalStateException("Connection has been released"); } } 1.67.2.1 +33 -33 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.67 retrieving revision 1.67.2.1 diff -u -r1.67 -r1.67.2.1 --- HttpConnection.java 26 May 2003 22:07:21 -0000 1.67 +++ HttpConnection.java 31 Jul 2003 02:31:09 -0000 1.67.2.1 @@ -247,32 +247,6 @@ throw new IllegalArgumentException("protocol is null"); } - if (LOG.isDebugEnabled()) { - StringBuffer buffer = new StringBuffer(); - buffer.append("Creating connection for "); - buffer.append(host); - if (virtualHost != null) { - buffer.append("["); - buffer.append(virtualHost); - buffer.append("]"); - } - if (port < 0) { - buffer.append(":"); - buffer.append(port); - } - if (proxyHost != null) { - buffer.append(" via "); - buffer.append(proxyHost); - if (proxyPort < 0) { - buffer.append(":"); - buffer.append(proxyPort); - } - } - buffer.append(" using protocol "); - buffer.append(protocol.toString()); - LOG.debug(buffer.toString()); - } - proxyHostName = proxyHost; proxyPortNumber = proxyPort; hostName = host; @@ -476,7 +450,7 @@ * @return <tt>true</tt> if I am connected */ public boolean isOpen() { - if (used && isStale()) { + if (used && isStaleCheckingEnabled() && isStale()) { LOG.debug("Connection is stale, closing..."); close(); } @@ -484,7 +458,30 @@ } /** - * Determines whether a connection is "stale", which is to say that either + * Tests if stale checking is enabled. + * + * @return <code>true</code> if enabled + * + * @see #isStale() + */ + public boolean isStaleCheckingEnabled() { + return staleCheckingEnabled; + } + + /** + * Sets whether or not isStale() will be called when testing if this connection is open. + * + * @param staleCheckingEnabled <code>true</code> to enable isStale() + * + * @see #isStale() + * @see #isOpen() + */ + public void setStaleCheckingEnabled(boolean staleCheckEnabled) { + this.staleCheckingEnabled = staleCheckEnabled; + } + + /** + * Determines whether this connection is "stale", which is to say that either * it is no longer open, or an attempt to read the connection would fail. * * <p>Unfortunately, due to the limitations of the JREs prior to 1.4, it is @@ -1415,11 +1412,14 @@ /** TCP_NODELAY socket value */ private boolean soNodelay = true; - /** Whether or not the _socket is a secure one. Note the difference to _ssl */ + /** Whether or not the socket is a secure one. */ private boolean usingSecureSocket = false; /** Whether I am tunneling a proxy or not */ private boolean tunnelEstablished = false; + + /** Whether or not isStale() is used by isOpen() */ + private boolean staleCheckingEnabled = true; /** Timeout until connection established (Socket created). 0 means no timeout. */ private int connectTimeout = 0; 1.11.2.1 +46 -4 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HostConfiguration.java Index: HostConfiguration.java =================================================================== RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HostConfiguration.java,v retrieving revision 1.11 retrieving revision 1.11.2.1 diff -u -r1.11 -r1.11.2.1 --- HostConfiguration.java 12 May 2003 02:42:42 -0000 1.11 +++ HostConfiguration.java 31 Jul 2003 02:31:09 -0000 1.11.2.1 @@ -104,7 +104,7 @@ /** The local address to use when creating the socket, or null to use the default */ private InetAddress localAddress; - + /** * Constructor for HostConfiguration. */ @@ -152,6 +152,48 @@ public Object clone() { return new HostConfiguration(this); } + + + /** + * @see java.lang.Object#toString() + */ + public synchronized String toString() { + + boolean appendComma = false; + + StringBuffer b = new StringBuffer(50); + b.append("HostConfiguration["); + + if (isHostSet()) { + appendComma = true; + b.append("host=").append(host); + b.append(", protocol=").append(protocol); + b.append(", port=").append(port); + if (virtualHost != null) { + b.append(", virtualHost=").append(virtualHost); + } + } + if (isProxySet()) { + if (appendComma) { + b.append(", "); + } else { + appendComma = true; + } + b.append("proxyHost=").append(proxyHost); + b.append(", proxyPort=").append(proxyPort); + } + if (localAddress != null) { + if (appendComma) { + b.append(", "); + } else { + appendComma = true; + } + b.append("localAddress=").append(localAddress); + } + + b.append("]"); + return b.toString(); + } /** * Tests if the host configuration equals the configuraiton set on the
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]