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
This commit is contained in:
Oleg Kalnichevski 2011-08-11 07:46:35 +00:00
parent ec85b40b80
commit 46f309f7c9
5 changed files with 68 additions and 69 deletions

View File

@ -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("=================================");

View File

@ -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;

View File

@ -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
*/

View File

@ -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() {

View File

@ -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()));