Eliminated synchronization overhead introduced by the connection backoff code

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1156175 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2011-08-10 13:34:06 +00:00
parent 444c6bf0e8
commit bf13db8115
1 changed files with 32 additions and 39 deletions

View File

@ -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();
}
@ -488,9 +477,6 @@ public abstract class AbstractHttpClient implements HttpClient {
}
public synchronized final ConnectionBackoffStrategy getConnectionBackoffStrategy() {
if (connectionBackoffStrategy == null) {
connectionBackoffStrategy = createConnectionBackoffStrategy();
}
return connectionBackoffStrategy;
}
@ -506,9 +492,6 @@ public abstract class AbstractHttpClient implements HttpClient {
}
public synchronized final BackoffManager getBackoffManager() {
if (backoffManager == null) {
backoffManager = createBackoffManager();
}
return backoffManager;
}
@ -827,6 +810,9 @@ public abstract class AbstractHttpClient implements HttpClient {
HttpContext execContext = null;
RequestDirector director = null;
HttpRoutePlanner routePlanner = null;
ConnectionBackoffStrategy connectionBackoffStrategy = null;
BackoffManager backoffManager = null;
// Initialize the request execution context making copies of
// all shared objects that are potentially threading unsafe.
@ -852,36 +838,43 @@ public abstract class AbstractHttpClient implements HttpClient {
getProxyAuthenticationHandler(),
getUserTokenHandler(),
determineParams(request));
routePlanner = getRoutePlanner();
connectionBackoffStrategy = getConnectionBackoffStrategy();
backoffManager = getBackoffManager();
}
try {
HttpHost targetForRoute = (target != null) ? target
: (HttpHost) determineParams(request).getParameter(
ClientPNames.DEFAULT_HOST);
HttpRoute route = getRoutePlanner().determineRoute(targetForRoute, request, execContext);
if (connectionBackoffStrategy != null && backoffManager != null) {
HttpHost targetForRoute = (target != null) ? target
: (HttpHost) determineParams(request).getParameter(
ClientPNames.DEFAULT_HOST);
HttpRoute route = routePlanner.determineRoute(targetForRoute, request, execContext);
HttpResponse out;
try {
out = director.execute(target, request, execContext);
} catch (RuntimeException re) {
if (getConnectionBackoffStrategy().shouldBackoff(re)) {
getBackoffManager().backOff(route);
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 (connectionBackoffStrategy.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);
}