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:
parent
ec85b40b80
commit
46f309f7c9
|
@ -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("=================================");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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()));
|
||||
|
|
Loading…
Reference in New Issue