You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2008/05/03 01:10:21 UTC
svn commit: r652945 - in /httpcomponents/httpclient/trunk: ./
module-client/src/main/java/org/apache/http/impl/conn/
module-client/src/main/java/org/apache/http/impl/conn/tsccm/
module-client/src/test/java/org/apache/http/conn/ module-client/src/test/j...
Author: olegk
Date: Fri May 2 16:10:20 2008
New Revision: 652945
URL: http://svn.apache.org/viewvc?rev=652945&view=rev
Log:
HTTPCLIENT-769: Do not pool connection marked non-reusable
Added:
httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestConnectionReuse.java (with props)
Modified:
httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractClientConnAdapter.java
httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPoolEntry.java
httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPooledConnAdapter.java
httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/SingleClientConnManager.java
httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/AbstractConnPool.java
httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/ConnPoolByRoute.java
httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java
httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestAllConn.java
httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestConnectionAutoRelease.java
httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/ClientConnAdapterMockup.java
httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/tsccm/TestConnPoolByRoute.java
httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/LocalTestServer.java
httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/ServerTestBase.java
Modified: httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/RELEASE_NOTES.txt?rev=652945&r1=652944&r2=652945&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpclient/trunk/RELEASE_NOTES.txt Fri May 2 16:10:20 2008
@@ -23,6 +23,9 @@
Changelog:
-------------------
+* [HTTPCLIENT-769] Do not pool connection marked non-reusable.
+ Contributed by Oleg Kalnichevski <olegk at apache.org>
+
* [HTTPCLIENT-763] Fixed problem with AbstractClientConnAdapter#abortConnection()
not releasing the connection if called from the main execution thread while
there is no blocking I/O operation.
Modified: httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractClientConnAdapter.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractClientConnAdapter.java?rev=652945&r1=652944&r2=652945&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractClientConnAdapter.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractClientConnAdapter.java Fri May 2 16:10:20 2008
@@ -359,30 +359,25 @@
}
aborted = true;
unmarkReusable();
-
- OperatedClientConnection conn = getWrappedConnection();
-
- if (conn != null) {
- try {
- conn.shutdown();
- } catch (IOException ignore) {
- }
- // Usually #abortConnection() is expected to be called from
- // a helper thread in order to unblock the main execution thread
- // blocked in an I/O operation. It may be unsafe to call
- // #releaseConnection() from the helper thread, so we have to rely
- // on an IOException thrown by the closed socket on the main thread
- // to trigger the release of the connection back to the
- // connection manager.
- //
- // However, if this method is called from the main execution thread
- // it should be safe to release the connection immediately. Besides,
- // this also helps ensure the connection gets released back to the
- // manager if #abortConnection() is called from the main execution
- // thread while there is no blocking I/O operation.
- if (executionThread.equals(Thread.currentThread())) {
- releaseConnection();
- }
+ try {
+ shutdown();
+ } catch (IOException ignore) {
+ }
+ // Usually #abortConnection() is expected to be called from
+ // a helper thread in order to unblock the main execution thread
+ // blocked in an I/O operation. It may be unsafe to call
+ // #releaseConnection() from the helper thread, so we have to rely
+ // on an IOException thrown by the closed socket on the main thread
+ // to trigger the release of the connection back to the
+ // connection manager.
+ //
+ // However, if this method is called from the main execution thread
+ // it should be safe to release the connection immediately. Besides,
+ // this also helps ensure the connection gets released back to the
+ // manager if #abortConnection() is called from the main execution
+ // thread while there is no blocking I/O operation.
+ if (executionThread.equals(Thread.currentThread())) {
+ releaseConnection();
}
}
Modified: httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPoolEntry.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPoolEntry.java?rev=652945&r1=652944&r2=652945&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPoolEntry.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPoolEntry.java Fri May 2 16:10:20 2008
@@ -299,12 +299,9 @@
/**
- * Tracks close or shutdown of the connection.
- * There is no distinction between the two, the route is dropped
- * in both cases. This method should be called regardless of
- * whether the close or shutdown succeeds or triggers an error.
+ * Resets tracked route.
*/
- public void closing() {
+ protected void resetTrackedRoute() {
tracker = null;
}
Modified: httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPooledConnAdapter.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPooledConnAdapter.java?rev=652945&r1=652944&r2=652945&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPooledConnAdapter.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPooledConnAdapter.java Fri May 2 16:10:20 2008
@@ -151,7 +151,7 @@
// non-javadoc, see interface HttpConnection
public void close() throws IOException {
if (poolEntry != null)
- poolEntry.closing();
+ poolEntry.resetTrackedRoute();
OperatedClientConnection conn = getWrappedConnection();
if (conn != null) {
@@ -162,7 +162,7 @@
// non-javadoc, see interface HttpConnection
public void shutdown() throws IOException {
if (poolEntry != null)
- poolEntry.closing();
+ poolEntry.resetTrackedRoute();
OperatedClientConnection conn = getWrappedConnection();
if (conn != null) {
Modified: httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/SingleClientConnManager.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/SingleClientConnManager.java?rev=652945&r1=652944&r2=652945&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/SingleClientConnManager.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/SingleClientConnManager.java Fri May 2 16:10:20 2008
@@ -283,7 +283,6 @@
} finally {
sca.detach();
managedConn = null;
- uniquePoolEntry.tracker = null;
lastReleaseTime = System.currentTimeMillis();
}
} // releaseConnection
@@ -374,7 +373,7 @@
protected void close()
throws IOException {
- closing();
+ resetTrackedRoute();
if (connection.isOpen())
connection.close();
}
@@ -386,7 +385,7 @@
protected void shutdown()
throws IOException {
- closing();
+ resetTrackedRoute();
if (connection.isOpen())
connection.shutdown();
}
Modified: httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/AbstractConnPool.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/AbstractConnPool.java?rev=652945&r1=652944&r2=652945&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/AbstractConnPool.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/AbstractConnPool.java Fri May 2 16:10:20 2008
@@ -183,8 +183,10 @@
* attempt to determine whether it can be re-used or not.
*
* @param entry the entry for the connection to release
+ * @param reusable <code>true</code> if the entry is deemed
+ * reusable, <code>false</code> otherwise.
*/
- public abstract void freeEntry(BasicPoolEntry entry)
+ public abstract void freeEntry(BasicPoolEntry entry, boolean reusable)
;
Modified: httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/ConnPoolByRoute.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/ConnPoolByRoute.java?rev=652945&r1=652944&r2=652945&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/ConnPoolByRoute.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/ConnPoolByRoute.java Fri May 2 16:10:20 2008
@@ -369,7 +369,7 @@
// non-javadoc, see base class AbstractConnPool
@Override
- public void freeEntry(BasicPoolEntry entry) {
+ public void freeEntry(BasicPoolEntry entry, boolean reusable) {
HttpRoute route = entry.getPlannedRoute();
if (LOG.isDebugEnabled()) {
@@ -391,17 +391,15 @@
RouteSpecificPool rospl = getRoutePool(route, true);
- rospl.freeEntry(entry);
- freeConnections.add(entry);
-
- if (numConnections == 0) {
- // for some reason this pool didn't already exist
- LOG.error("Master connection pool not found: " + route);
- numConnections = 1;
+ if (reusable) {
+ rospl.freeEntry(entry);
+ freeConnections.add(entry);
+ idleConnHandler.add(entry.getConnection());
+ } else {
+ rospl.dropEntry();
+ numConnections--;
}
- idleConnHandler.add(entry.getConnection());
-
notifyWaitingThread(rospl);
} finally {
Modified: httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java?rev=652945&r1=652944&r2=652945&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java Fri May 2 16:10:20 2008
@@ -222,9 +222,11 @@
iox);
} finally {
BasicPoolEntry entry = (BasicPoolEntry) hca.getPoolEntry();
+ boolean reusable = hca.isMarkedReusable();
hca.detach();
- if (entry != null) // is it worth to bother with this check? @@@
- connectionPool.freeEntry(entry);
+ if (entry != null) {
+ connectionPool.freeEntry(entry, reusable);
+ }
}
}
Modified: httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestAllConn.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestAllConn.java?rev=652945&r1=652944&r2=652945&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestAllConn.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestAllConn.java Fri May 2 16:10:20 2008
@@ -50,6 +50,7 @@
suite.addTest(TestScheme.suite());
suite.addTest(TestExceptions.suite());
+ suite.addTest(TestConnectionReuse.suite());
suite.addTest(TestConnectionAutoRelease.suite());
suite.addTest(TestAllConnParams.suite());
suite.addTest(TestAllRouting.suite());
Modified: httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestConnectionAutoRelease.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestConnectionAutoRelease.java?rev=652945&r1=652944&r2=652945&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestConnectionAutoRelease.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestConnectionAutoRelease.java Fri May 2 16:10:20 2008
@@ -200,8 +200,8 @@
assertNotNull(e);
httpget.abort();
- // Expect one connection in the pool
- assertEquals(1, mgr.getConnectionsInPool());
+ // Expect zero connections in the pool
+ assertEquals(0, mgr.getConnectionsInPool());
// Make sure one connection is available
connreq = mgr.requestConnection(new HttpRoute(target), null);
@@ -281,8 +281,8 @@
}
- // Expect one connection in the pool
- assertEquals(1, mgr.getConnectionsInPool());
+ // Expect zero connections in the pool
+ assertEquals(0, mgr.getConnectionsInPool());
// Make sure one connection is available
connreq = mgr.requestConnection(new HttpRoute(target), null);
Added: httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestConnectionReuse.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestConnectionReuse.java?rev=652945&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestConnectionReuse.java (added)
+++ httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestConnectionReuse.java Fri May 2 16:10:20 2008
@@ -0,0 +1,345 @@
+/*
+ * $HeadURL:$
+ * $Revision:$
+ * $Date:$
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.conn;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.URI;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpResponseInterceptor;
+import org.apache.http.HttpVersion;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.conn.params.ConnPerRouteBean;
+import org.apache.http.conn.params.HttpConnectionManagerParams;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.scheme.SocketFactory;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.localserver.LocalTestServer;
+import org.apache.http.localserver.RandomHandler;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.protocol.BasicHttpProcessor;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.ResponseConnControl;
+import org.apache.http.protocol.ResponseContent;
+import org.apache.http.protocol.ResponseDate;
+import org.apache.http.protocol.ResponseServer;
+
+public class TestConnectionReuse extends TestCase {
+
+ public TestConnectionReuse(String testName) {
+ super(testName);
+ }
+
+ public static void main(String args[]) {
+ String[] testCaseName = { TestConnectionReuse.class.getName() };
+ junit.textui.TestRunner.main(testCaseName);
+ }
+
+ public static Test suite() {
+ return new TestSuite(TestConnectionReuse.class);
+ }
+
+ protected LocalTestServer localServer;
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (this.localServer != null) {
+ this.localServer.stop();
+ }
+ }
+
+
+ public void testReuseOfPersistentConnections() throws Exception {
+ BasicHttpProcessor httpproc = new BasicHttpProcessor();
+ httpproc.addInterceptor(new ResponseDate());
+ httpproc.addInterceptor(new ResponseServer());
+ httpproc.addInterceptor(new ResponseContent());
+ httpproc.addInterceptor(new ResponseConnControl());
+
+ this.localServer = new LocalTestServer(httpproc, null);
+ this.localServer.register("/random/*", new RandomHandler());
+ this.localServer.start();
+
+ InetSocketAddress saddress = (InetSocketAddress) this.localServer.getServiceAddress();
+
+ HttpParams params = new BasicHttpParams();
+ HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+ HttpProtocolParams.setContentCharset(params, "UTF-8");
+ HttpProtocolParams.setUserAgent(params, "TestAgent/1.1");
+ HttpProtocolParams.setUseExpectContinue(params, false);
+ HttpConnectionParams.setStaleCheckingEnabled(params, false);
+ HttpConnectionManagerParams.setMaxTotalConnections(params, 5);
+ HttpConnectionManagerParams.setMaxConnectionsPerRoute(params,
+ new ConnPerRouteBean(5));
+
+ SchemeRegistry supportedSchemes = new SchemeRegistry();
+ SocketFactory sf = PlainSocketFactory.getSocketFactory();
+ supportedSchemes.register(new Scheme("http", sf, 80));
+
+ ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(
+ params, supportedSchemes);
+
+ DefaultHttpClient client = new DefaultHttpClient(mgr, params);
+
+ HttpHost target = new HttpHost(saddress.getHostName(), saddress.getPort(), "http");
+
+ WorkerThread[] workers = new WorkerThread[10];
+ for (int i = 0; i < workers.length; i++) {
+ workers[i] = new WorkerThread(
+ client,
+ target,
+ new URI("/random/2000"),
+ 10, false);
+ }
+
+ for (int i = 0; i < workers.length; i++) {
+ WorkerThread worker = workers[i];
+ worker.start();
+ }
+ for (int i = 0; i < workers.length; i++) {
+ WorkerThread worker = workers[i];
+ workers[i].join(10000);
+ Exception ex = worker.getException();
+ if (ex != null) {
+ throw ex;
+ }
+ }
+
+ // Expect some connection in the pool
+ assertTrue(mgr.getConnectionsInPool() > 0);
+
+ mgr.shutdown();
+ }
+
+ private static class AlwaysCloseConn implements HttpResponseInterceptor {
+
+ public void process(
+ final HttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+ response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
+ }
+
+ }
+
+ public void testReuseOfClosedConnections() throws Exception {
+ BasicHttpProcessor httpproc = new BasicHttpProcessor();
+ httpproc.addInterceptor(new ResponseDate());
+ httpproc.addInterceptor(new ResponseServer());
+ httpproc.addInterceptor(new ResponseContent());
+ httpproc.addInterceptor(new AlwaysCloseConn());
+
+ this.localServer = new LocalTestServer(httpproc, null);
+ this.localServer.register("/random/*", new RandomHandler());
+ this.localServer.start();
+
+ InetSocketAddress saddress = (InetSocketAddress) this.localServer.getServiceAddress();
+
+ HttpParams params = new BasicHttpParams();
+ HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+ HttpProtocolParams.setContentCharset(params, "UTF-8");
+ HttpProtocolParams.setUserAgent(params, "TestAgent/1.1");
+ HttpProtocolParams.setUseExpectContinue(params, false);
+ HttpConnectionParams.setStaleCheckingEnabled(params, false);
+ HttpConnectionManagerParams.setMaxTotalConnections(params, 5);
+ HttpConnectionManagerParams.setMaxConnectionsPerRoute(params,
+ new ConnPerRouteBean(5));
+
+ SchemeRegistry supportedSchemes = new SchemeRegistry();
+ SocketFactory sf = PlainSocketFactory.getSocketFactory();
+ supportedSchemes.register(new Scheme("http", sf, 80));
+
+ ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(
+ params, supportedSchemes);
+
+ DefaultHttpClient client = new DefaultHttpClient(mgr, params);
+
+ HttpHost target = new HttpHost(saddress.getHostName(), saddress.getPort(), "http");
+
+ WorkerThread[] workers = new WorkerThread[10];
+ for (int i = 0; i < workers.length; i++) {
+ workers[i] = new WorkerThread(
+ client,
+ target,
+ new URI("/random/2000"),
+ 10, false);
+ }
+
+ for (int i = 0; i < workers.length; i++) {
+ WorkerThread worker = workers[i];
+ worker.start();
+ }
+ for (int i = 0; i < workers.length; i++) {
+ WorkerThread worker = workers[i];
+ workers[i].join(10000);
+ Exception ex = worker.getException();
+ if (ex != null) {
+ throw ex;
+ }
+ }
+
+ // Expect zero connections in the pool
+ assertEquals(0, mgr.getConnectionsInPool());
+
+ mgr.shutdown();
+ }
+
+ public void testReuseOfAbortedConnections() throws Exception {
+ BasicHttpProcessor httpproc = new BasicHttpProcessor();
+ httpproc.addInterceptor(new ResponseDate());
+ httpproc.addInterceptor(new ResponseServer());
+ httpproc.addInterceptor(new ResponseContent());
+ httpproc.addInterceptor(new ResponseConnControl());
+
+ this.localServer = new LocalTestServer(httpproc, null);
+ this.localServer.register("/random/*", new RandomHandler());
+ this.localServer.start();
+
+ InetSocketAddress saddress = (InetSocketAddress) this.localServer.getServiceAddress();
+
+ HttpParams params = new BasicHttpParams();
+ HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+ HttpProtocolParams.setContentCharset(params, "UTF-8");
+ HttpProtocolParams.setUserAgent(params, "TestAgent/1.1");
+ HttpProtocolParams.setUseExpectContinue(params, false);
+ HttpConnectionParams.setStaleCheckingEnabled(params, false);
+ HttpConnectionManagerParams.setMaxTotalConnections(params, 5);
+ HttpConnectionManagerParams.setMaxConnectionsPerRoute(params,
+ new ConnPerRouteBean(5));
+
+ SchemeRegistry supportedSchemes = new SchemeRegistry();
+ SocketFactory sf = PlainSocketFactory.getSocketFactory();
+ supportedSchemes.register(new Scheme("http", sf, 80));
+
+ ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(
+ params, supportedSchemes);
+
+ DefaultHttpClient client = new DefaultHttpClient(mgr, params);
+
+ HttpHost target = new HttpHost(saddress.getHostName(), saddress.getPort(), "http");
+
+ WorkerThread[] workers = new WorkerThread[10];
+ for (int i = 0; i < workers.length; i++) {
+ workers[i] = new WorkerThread(
+ client,
+ target,
+ new URI("/random/2000"),
+ 10, true);
+ }
+
+ for (int i = 0; i < workers.length; i++) {
+ WorkerThread worker = workers[i];
+ worker.start();
+ }
+ for (int i = 0; i < workers.length; i++) {
+ WorkerThread worker = workers[i];
+ workers[i].join(10000);
+ Exception ex = worker.getException();
+ if (ex != null) {
+ throw ex;
+ }
+ }
+
+ // Expect zero connections in the pool
+ assertEquals(0, mgr.getConnectionsInPool());
+
+ mgr.shutdown();
+ }
+
+ private static class WorkerThread extends Thread {
+
+ private final URI requestURI;
+ private final HttpHost target;
+ private final HttpClient httpclient;
+ private final int repetitions;
+ private final boolean forceClose;
+
+ private volatile Exception exception;
+
+ public WorkerThread(
+ final HttpClient httpclient,
+ final HttpHost target,
+ final URI requestURI,
+ int repetitions,
+ boolean forceClose) {
+ super();
+ this.httpclient = httpclient;
+ this.requestURI = requestURI;
+ this.target = target;
+ this.repetitions = repetitions;
+ this.forceClose = forceClose;
+ }
+
+ @Override
+ public void run() {
+ try {
+ for (int i = 0; i < this.repetitions; i++) {
+ HttpGet httpget = new HttpGet(this.requestURI);
+ HttpResponse response = this.httpclient.execute(
+ this.target,
+ httpget);
+ if (this.forceClose) {
+ httpget.abort();
+ } else {
+ HttpEntity entity = response.getEntity();
+ if (entity != null) {
+ entity.consumeContent();
+ }
+ }
+ }
+ } catch (Exception ex) {
+ this.exception = ex;
+ }
+ }
+
+ public Exception getException() {
+ return exception;
+ }
+
+ }
+
+}
Propchange: httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestConnectionReuse.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestConnectionReuse.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/TestConnectionReuse.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/ClientConnAdapterMockup.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/ClientConnAdapterMockup.java?rev=652945&r1=652944&r2=652945&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/ClientConnAdapterMockup.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/ClientConnAdapterMockup.java Fri May 2 16:10:20 2008
@@ -64,7 +64,6 @@
}
public void shutdown() {
- throw new UnsupportedOperationException("just a mockup");
}
public void tunnelTarget(boolean secure, HttpParams params) {
Modified: httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/tsccm/TestConnPoolByRoute.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/tsccm/TestConnPoolByRoute.java?rev=652945&r1=652944&r2=652945&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/tsccm/TestConnPoolByRoute.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/tsccm/TestConnPoolByRoute.java Fri May 2 16:10:20 2008
@@ -1,7 +1,7 @@
/*
- * $HeadURL:$
- * $Revision:$
- * $Date:$
+ * $HeadURL$
+ * $Revision$
+ * $Date$
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -95,7 +95,7 @@
}
// Free one
- connPool.freeEntry(e3);
+ connPool.freeEntry(e3, true);
// This time the request should succeed
PoolEntryRequest r5 = connPool.requestPoolEntry(route, null);
@@ -136,9 +136,9 @@
e3.setState(Integer.valueOf(3));
// Release entries
- connPool.freeEntry(e1);
- connPool.freeEntry(e2);
- connPool.freeEntry(e3);
+ connPool.freeEntry(e1, true);
+ connPool.freeEntry(e2, true);
+ connPool.freeEntry(e3, true);
// Request statefull entries
PoolEntryRequest r4 = connPool.requestPoolEntry(route, Integer.valueOf(2));
@@ -160,9 +160,9 @@
assertTrue(e6 == e1);
// Release entries again
- connPool.freeEntry(e4);
- connPool.freeEntry(e5);
- connPool.freeEntry(e6);
+ connPool.freeEntry(e4, true);
+ connPool.freeEntry(e5, true);
+ connPool.freeEntry(e6, true);
// Request an entry with a state not avaialable in the pool
PoolEntryRequest r7 = connPool.requestPoolEntry(route, Integer.valueOf(4));
Modified: httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/LocalTestServer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/LocalTestServer.java?rev=652945&r1=652944&r2=652945&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/LocalTestServer.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/LocalTestServer.java Fri May 2 16:10:20 2008
@@ -35,6 +35,7 @@
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
+import java.net.SocketAddress;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -157,7 +158,7 @@
.setBooleanParameter(CoreConnectionPNames.TCP_NODELAY,
true)
.setParameter(CoreProtocolPNames.ORIGIN_SERVER,
- "Jakarta-HttpComponents-LocalTestServer/1.1");
+ "LocalTestServer/1.1");
return params;
}
@@ -280,6 +281,19 @@
/**
+ * Obtains the local address the server is listening on
+ *
+ * @return the service address
+ */
+ public SocketAddress getServiceAddress() {
+ ServerSocket ssock = servicedSocket; // avoid synchronization
+ if (ssock == null)
+ throw new IllegalStateException("not running");
+
+ return ssock.getLocalSocketAddress();
+ }
+
+ /**
* The request listener.
* Accepts incoming connections and launches a service thread.
*/
Modified: httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/ServerTestBase.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/ServerTestBase.java?rev=652945&r1=652944&r2=652945&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/ServerTestBase.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/ServerTestBase.java Fri May 2 16:10:20 2008
@@ -119,7 +119,7 @@
HttpProtocolParams.setContentCharset
(defaultParams, "UTF-8");
HttpProtocolParams.setUserAgent
- (defaultParams, "Jakarta-HttpComponents-Test/1.1");
+ (defaultParams, "TestAgent/1.1");
HttpProtocolParams.setUseExpectContinue
(defaultParams, false);
}