From 46f309f7c95af63d4e18d078fdd7c44c7260f2f5 Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Thu, 11 Aug 2011 07:46:35 +0000 Subject: [PATCH] Improved #detach method implementation git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/branches/conn-mgmt-redesign@1156522 13f79535-47bb-0310-9956-ffa450edef68 --- .../http/client/benchmark/Benchmark.java | 14 +-- .../client/benchmark/TestHttpClient4.java | 1 + .../http/impl/client/AbstractHttpClient.java | 90 +++++++++---------- .../conn/ManagedClientConnectionImpl.java | 29 +++--- .../conn/PoolingClientConnectionManager.java | 3 +- 5 files changed, 68 insertions(+), 69 deletions(-) diff --git a/httpclient-benchmark/src/main/java/org/apache/http/client/benchmark/Benchmark.java b/httpclient-benchmark/src/main/java/org/apache/http/client/benchmark/Benchmark.java index 4d612fba7..9014d34d8 100644 --- a/httpclient-benchmark/src/main/java/org/apache/http/client/benchmark/Benchmark.java +++ b/httpclient-benchmark/src/main/java/org/apache/http/client/benchmark/Benchmark.java @@ -48,7 +48,7 @@ public class Benchmark { public static void main(String[] args) throws Exception { - String ns = System.getProperty("hc.benchmark.n-requests", "200000"); + String ns = System.getProperty("hc.benchmark.n-requests", "400000"); String nc = System.getProperty("hc.benchmark.concurrent", "20"); String cls = System.getProperty("hc.benchmark.content-len", "2048"); @@ -76,12 +76,12 @@ public class Benchmark { int port = connector.getLocalPort(); TestHttpAgent[] agents = new TestHttpAgent[] { - new TestHttpClient3(), - new TestHttpJRE(), - new TestHttpCore(), +// new TestHttpClient3(), +// new TestHttpJRE(), +// new TestHttpCore(), new TestHttpClient4(), - new TestJettyHttpClient(), - new TestNingHttpClient() +// new TestJettyHttpClient(), +// new TestNingHttpClient() }; byte[] content = new byte[contentLen]; @@ -99,7 +99,7 @@ public class Benchmark { try { agent.init(); // Warm up - agent.get(warmup, 5, 500); + agent.get(warmup, 500, 2); // Sleep a little Thread.sleep(5000); System.out.println("================================="); diff --git a/httpclient-benchmark/src/main/java/org/apache/http/client/benchmark/TestHttpClient4.java b/httpclient-benchmark/src/main/java/org/apache/http/client/benchmark/TestHttpClient4.java index abe42c587..bc88c1b06 100644 --- a/httpclient-benchmark/src/main/java/org/apache/http/client/benchmark/TestHttpClient4.java +++ b/httpclient-benchmark/src/main/java/org/apache/http/client/benchmark/TestHttpClient4.java @@ -43,6 +43,7 @@ import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; diff --git a/httpclient/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java b/httpclient/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java index 67a4990cc..01ff67898 100644 --- a/httpclient/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java +++ b/httpclient/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java @@ -254,11 +254,11 @@ public abstract class AbstractHttpClient implements HttpClient { /** The connection backoff strategy. */ @GuardedBy("this") private ConnectionBackoffStrategy connectionBackoffStrategy; - + /** The backoff manager. */ @GuardedBy("this") private BackoffManager backoffManager; - + /** * Creates a new HTTP client. * @@ -373,17 +373,6 @@ public abstract class AbstractHttpClient implements HttpClient { return registry; } - protected BackoffManager createBackoffManager() { - return new BackoffManager() { - public void backOff(HttpRoute ignored) { } - public void probe(HttpRoute ignored) { } - }; - } - - protected ConnectionBackoffStrategy createConnectionBackoffStrategy() { - return new NullBackoffStrategy(); - } - protected HttpRequestExecutor createRequestExecutor() { return new HttpRequestExecutor(); } @@ -481,19 +470,16 @@ public abstract class AbstractHttpClient implements HttpClient { supportedAuthSchemes = createAuthSchemeRegistry(); } return supportedAuthSchemes; - } - + } + public synchronized void setAuthSchemes(final AuthSchemeRegistry authSchemeRegistry) { supportedAuthSchemes = authSchemeRegistry; } public synchronized final ConnectionBackoffStrategy getConnectionBackoffStrategy() { - if (connectionBackoffStrategy == null) { - connectionBackoffStrategy = createConnectionBackoffStrategy(); - } return connectionBackoffStrategy; } - + public synchronized void setConnectionBackoffStrategy(final ConnectionBackoffStrategy strategy) { connectionBackoffStrategy = strategy; } @@ -506,16 +492,13 @@ public abstract class AbstractHttpClient implements HttpClient { } public synchronized final BackoffManager getBackoffManager() { - if (backoffManager == null) { - backoffManager = createBackoffManager(); - } return backoffManager; } - + public synchronized void setBackoffManager(final BackoffManager manager) { backoffManager = manager; } - + public synchronized void setCookieSpecs(final CookieSpecRegistry cookieSpecRegistry) { supportedCookieSpecs = cookieSpecRegistry; } @@ -827,6 +810,9 @@ public abstract class AbstractHttpClient implements HttpClient { HttpContext execContext = null; RequestDirector director = null; + ConnectionBackoffStrategy connectionBackoffStrategy = null; + BackoffManager backoffManager = null; + HttpRoutePlanner httpRoutePlanner = null; // Initialize the request execution context making copies of // all shared objects that are potentially threading unsafe. @@ -852,36 +838,44 @@ public abstract class AbstractHttpClient implements HttpClient { getProxyAuthenticationHandler(), getUserTokenHandler(), determineParams(request)); + + connectionBackoffStrategy = getConnectionBackoffStrategy(); + backoffManager = getBackoffManager(); + httpRoutePlanner = getRoutePlanner(); } try { - HttpHost targetForRoute = (target != null) ? target - : (HttpHost) determineParams(request).getParameter( - ClientPNames.DEFAULT_HOST); - HttpRoute route = getRoutePlanner().determineRoute(targetForRoute, request, execContext); - - HttpResponse out; - try { - out = director.execute(target, request, execContext); - } catch (RuntimeException re) { - if (getConnectionBackoffStrategy().shouldBackoff(re)) { - getBackoffManager().backOff(route); + if (connectionBackoffStrategy != null && backoffManager != null) { + HttpHost targetForRoute = (target != null) ? target + : (HttpHost) determineParams(request).getParameter( + ClientPNames.DEFAULT_HOST); + HttpRoute route = httpRoutePlanner.determineRoute(targetForRoute, request, execContext); + + HttpResponse out; + try { + out = director.execute(target, request, execContext); + } catch (RuntimeException re) { + if (connectionBackoffStrategy.shouldBackoff(re)) { + backoffManager.backOff(route); + } + throw re; + } catch (Exception e) { + if (connectionBackoffStrategy.shouldBackoff(e)) { + backoffManager.backOff(route); + } + if (e instanceof HttpException) throw (HttpException)e; + if (e instanceof IOException) throw (IOException)e; + throw new UndeclaredThrowableException(e); } - throw re; - } catch (Exception e) { - if (getConnectionBackoffStrategy().shouldBackoff(e)) { - getBackoffManager().backOff(route); + if (getConnectionBackoffStrategy().shouldBackoff(out)) { + backoffManager.backOff(route); + } else { + backoffManager.probe(route); } - if (e instanceof HttpException) throw (HttpException)e; - if (e instanceof IOException) throw (IOException)e; - throw new RuntimeException("unexpected exception", e); - } - if (getConnectionBackoffStrategy().shouldBackoff(out)) { - getBackoffManager().backOff(route); + return out; } else { - getBackoffManager().probe(route); + return director.execute(target, request, execContext); } - return out; } catch(HttpException httpException) { throw new ClientProtocolException(httpException); } @@ -915,7 +909,7 @@ public abstract class AbstractHttpClient implements HttpClient { stateHandler, params); } - + /** * @since 4.1 */ diff --git a/httpclient/src/main/java/org/apache/http/impl/conn/ManagedClientConnectionImpl.java b/httpclient/src/main/java/org/apache/http/impl/conn/ManagedClientConnectionImpl.java index c17cf583d..37b5d9ac9 100644 --- a/httpclient/src/main/java/org/apache/http/impl/conn/ManagedClientConnectionImpl.java +++ b/httpclient/src/main/java/org/apache/http/impl/conn/ManagedClientConnectionImpl.java @@ -85,12 +85,10 @@ class ManagedClientConnectionImpl implements ManagedClientConnection { return this.poolEntry; } - void detach() { + HttpPoolEntry detach() { + HttpPoolEntry local = this.poolEntry; this.poolEntry = null; - } - - boolean isDetached() { - return this.poolEntry == null; + return local; } public ClientConnectionManager getManager() { @@ -113,6 +111,14 @@ class ManagedClientConnectionImpl implements ManagedClientConnection { return local.getConnection(); } + private HttpPoolEntry ensurePoolEntry() { + HttpPoolEntry local = this.poolEntry; + if (local == null) { + throw new ConnectionShutdownException(); + } + return local; + } + public void close() throws IOException { OperatedClientConnection conn = getConnection(); if (conn != null) { @@ -254,11 +260,8 @@ class ManagedClientConnectionImpl implements ManagedClientConnection { } public HttpRoute getRoute() { - HttpPoolEntry local = this.poolEntry; - if (local == null) { - throw new ConnectionShutdownException(); - } - return poolEntry.getEffectiveRoute(); + HttpPoolEntry local = ensurePoolEntry(); + return local.getEffectiveRoute(); } public void open( @@ -403,11 +406,13 @@ class ManagedClientConnectionImpl implements ManagedClientConnection { } public Object getState() { - return this.poolEntry.getState(); + HttpPoolEntry local = ensurePoolEntry(); + return local.getState(); } public void setState(final Object state) { - this.poolEntry.setState(state); + HttpPoolEntry local = ensurePoolEntry(); + local.setState(state); } public void markReusable() { diff --git a/httpclient/src/main/java/org/apache/http/impl/conn/PoolingClientConnectionManager.java b/httpclient/src/main/java/org/apache/http/impl/conn/PoolingClientConnectionManager.java index 5a39d8f92..4d65ec8fd 100644 --- a/httpclient/src/main/java/org/apache/http/impl/conn/PoolingClientConnectionManager.java +++ b/httpclient/src/main/java/org/apache/http/impl/conn/PoolingClientConnectionManager.java @@ -229,7 +229,7 @@ public class PoolingClientConnectionManager implements ClientConnectionManager, } synchronized (managedConn) { - HttpPoolEntry entry = managedConn.getPoolEntry(); + HttpPoolEntry entry = managedConn.detach(); if (entry == null) { return; } @@ -255,7 +255,6 @@ public class PoolingClientConnectionManager implements ClientConnectionManager, } } finally { this.pool.release(entry, managedConn.isMarkedReusable()); - managedConn.detach(); } if (this.log.isDebugEnabled()) { this.log.debug("Connection released: " + format(entry) + formatStats(entry.getRoute()));