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 2007/05/07 11:07:47 UTC
svn commit: r535794 - in
/jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client:
AbstractHttpClient.java DefaultClientRequestDirector.java
DefaultHttpClient.java
Author: olegk
Date: Mon May 7 02:07:44 2007
New Revision: 535794
URL: http://svn.apache.org/viewvc?view=rev&rev=535794
Log:
Implemented HTTP request retry handling
Modified:
jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/AbstractHttpClient.java
jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/DefaultClientRequestDirector.java
jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/DefaultHttpClient.java
Modified: jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/AbstractHttpClient.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/AbstractHttpClient.java?view=diff&rev=535794&r1=535793&r2=535794
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/AbstractHttpClient.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/AbstractHttpClient.java Mon May 7 02:07:44 2007
@@ -44,6 +44,7 @@
import org.apache.http.auth.AuthSchemeRegistry;
import org.apache.http.client.ClientRequestDirector;
import org.apache.http.client.HttpClient;
+import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.HttpState;
import org.apache.http.client.RoutedRequest;
import org.apache.http.conn.ClientConnectionManager;
@@ -93,6 +94,9 @@
/** The HTTP processor. */
private BasicHttpProcessor httpProcessor;
+ /** The request retry handler. */
+ private HttpRequestRetryHandler retryHandler;
+
/** The default HTTP state. */
private HttpState defaultState;
@@ -131,6 +135,9 @@
protected abstract BasicHttpProcessor createHttpProcessor();
+ protected abstract HttpRequestRetryHandler createHttpRequestRetryHandler();
+
+
protected abstract HttpState createHttpState();
@@ -209,6 +216,19 @@
}
+ public synchronized final HttpRequestRetryHandler getHttpRequestRetryHandler() {
+ if (retryHandler == null) {
+ retryHandler = createHttpRequestRetryHandler();
+ }
+ return retryHandler;
+ }
+
+
+ public synchronized void setHttpRequestRetryHandler(final HttpRequestRetryHandler retryHandler) {
+ this.retryHandler = retryHandler;
+ }
+
+
public synchronized final HttpState getState() {
if (defaultState == null) {
defaultState = createHttpState();
@@ -367,6 +387,7 @@
getConnectionManager(),
getConnectionReuseStrategy(),
getHttpProcessor().copy(),
+ getHttpRequestRetryHandler(),
getParams());
}
Modified: jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/DefaultClientRequestDirector.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/DefaultClientRequestDirector.java?view=diff&rev=535794&r1=535793&r2=535794
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/DefaultClientRequestDirector.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/DefaultClientRequestDirector.java Mon May 7 02:07:44 2007
@@ -33,6 +33,8 @@
import java.io.IOException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.http.ConnectionReuseStrategy;
import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
@@ -40,22 +42,23 @@
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientRequestDirector;
+import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.RoutedRequest;
import org.apache.http.client.methods.AbortableHttpRequest;
+import org.apache.http.client.params.HttpClientParams;
import org.apache.http.conn.BasicManagedEntity;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.HttpRoute;
import org.apache.http.conn.ManagedClientConnection;
import org.apache.http.conn.RouteDirector;
import org.apache.http.message.BasicHttpRequest;
+import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpExecutionContext;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.protocol.HttpRequestExecutor;
-
-
/**
* Default implementation of a client-side request director.
* <br/>
@@ -72,6 +75,8 @@
public class DefaultClientRequestDirector
implements ClientRequestDirector {
+ private static final Log LOG = LogFactory.getLog(DefaultClientRequestDirector.class);
+
/** The connection manager. */
protected final ClientConnectionManager connManager;
@@ -84,19 +89,45 @@
/** The HTTP protocol processor. */
protected final HttpProcessor httpProcessor;
+ /** The request retry handler. */
+ protected final HttpRequestRetryHandler retryHandler;
+
+ /** The HTTP parameters. */
+ protected final HttpParams params;
+
/** The currently allocated connection. */
protected ManagedClientConnection managedConn;
- public DefaultClientRequestDirector(ClientConnectionManager conman,
- ConnectionReuseStrategy reustrat,
- HttpProcessor httpProcessor,
- HttpParams params) {
+ public DefaultClientRequestDirector(
+ final ClientConnectionManager conman,
+ final ConnectionReuseStrategy reustrat,
+ final HttpProcessor httpProcessor,
+ final HttpRequestRetryHandler retryHandler,
+ final HttpParams params) {
+ if (conman == null) {
+ throw new IllegalArgumentException("Client connection manager may not be null");
+ }
+ if (reustrat == null) {
+ throw new IllegalArgumentException("Connection reuse strategy may not be null");
+ }
+ if (httpProcessor == null) {
+ throw new IllegalArgumentException("HTTP protocol processor may not be null");
+ }
+ if (retryHandler == null) {
+ throw new IllegalArgumentException("HTTP request retry handler may not be null");
+ }
+ if (params == null) {
+ throw new IllegalArgumentException("HTTP parameters may not be null");
+ }
this.connManager = conman;
this.reuseStrategy = reustrat;
- this.requestExec = new HttpRequestExecutor(params);
this.httpProcessor = httpProcessor;
+ this.retryHandler = retryHandler;
+ this.params = params;
+ this.requestExec = new HttpRequestExecutor(params);
+
this.managedConn = null;
//@@@ authentication?
@@ -126,6 +157,7 @@
//@@@ if redirects are followed, or for the whole sequence?
try {
+ int execCount = 0;
while (!done) {
allocateConnection(roureq.getRoute());
establishRoute(roureq.getRoute(), context);
@@ -145,7 +177,40 @@
context.setAttribute(HttpExecutionContext.HTTP_REQUEST,
prepreq);
- response = requestExec.execute(prepreq, managedConn, context);
+ execCount++;
+ try {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Attempt number " + execCount + " to execute request");
+ }
+
+ if (HttpConnectionParams.isStaleCheckingEnabled(params)) {
+ // validate connection
+ LOG.debug("Stale connection check");
+ if (managedConn.isStale()) {
+ LOG.debug("Stale connection detected");
+ managedConn.close();
+ }
+ }
+
+ response = requestExec.execute(prepreq, managedConn, context);
+
+ } catch (IOException ex) {
+ LOG.debug("Closing the connection.");
+ managedConn.close();
+ if (retryHandler.retryRequest(ex, execCount, context)) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("I/O exception ("+ ex.getClass().getName() +
+ ") caught when processing request: "
+ + ex.getMessage());
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(ex.getMessage(), ex);
+ }
+ LOG.info("Retrying request");
+ continue;
+ }
+ throw ex;
+ }
finalizeResponse(response, context);
@@ -184,15 +249,16 @@
* @throws HttpException in case of a problem
*/
protected void allocateConnection(HttpRoute route)
- throws HttpException {
+ throws HttpException, IOException {
// we assume that the connection would have been released
// if it was not appropriate for the route of the followup
- if (managedConn != null)
+ if (managedConn != null) {
return;
+ }
- //@@@ use connection manager timeout
- managedConn = connManager.getConnection(route);
+ long timeout = HttpClientParams.getConnectionManagerTimeout(params);
+ managedConn = connManager.getConnection(route, timeout);
} // allocateConnection
@@ -439,9 +505,7 @@
if (success) {
// Not in exception handling, there probably is a response.
// The connection is in or can be brought to a re-usable state.
- boolean reuse = false;
- if (reuseStrategy != null)
- reuse = reuseStrategy.keepAlive(response, context);
+ boolean reuse = reuseStrategy.keepAlive(response, context);
// check for entity, release connection if possible
if ((response == null) || (response.getEntity() == null) ||
@@ -462,9 +526,10 @@
//@@@ for now, just shut it down
try {
mcc.abortConnection();
- } catch (IOException ignore) {
- // can't allow exception while handling exception
- //@@@ log as debug or warning?
+ } catch (IOException ex) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(ex.getMessage(), ex);
+ }
}
}
} // cleanupConnection
Modified: jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/DefaultHttpClient.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/DefaultHttpClient.java?view=diff&rev=535794&r1=535793&r2=535794
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/DefaultHttpClient.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/impl/client/DefaultHttpClient.java Mon May 7 02:07:44 2007
@@ -37,6 +37,7 @@
import org.apache.http.HttpRequest;
import org.apache.http.HttpVersion;
import org.apache.http.auth.AuthSchemeRegistry;
+import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.HttpState;
import org.apache.http.client.RoutedRequest;
import org.apache.http.client.params.AuthPolicy;
@@ -202,6 +203,11 @@
httpproc.addInterceptor(new RequestAddCookies());
httpproc.addInterceptor(new ResponseProcessCookies());
return httpproc;
+ }
+
+
+ protected HttpRequestRetryHandler createHttpRequestRetryHandler() {
+ return new DefaultHttpRequestRetryHandler();
}