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 2012/06/11 17:12:07 UTC

svn commit: r1348893 - in /httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http: client/methods/HttpExecutionAware.java impl/client/exec/MainRequestExecutor.java impl/client/exec/ManagedEntity.java

Author: olegk
Date: Mon Jun 11 15:12:06 2012
New Revision: 1348893

URL: http://svn.apache.org/viewvc?rev=1348893&view=rev
Log:
Refactored handling of managed entities

Modified:
    httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/client/methods/HttpExecutionAware.java
    httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainRequestExecutor.java
    httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/ManagedEntity.java

Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/client/methods/HttpExecutionAware.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/client/methods/HttpExecutionAware.java?rev=1348893&r1=1348892&r2=1348893&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/client/methods/HttpExecutionAware.java (original)
+++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/client/methods/HttpExecutionAware.java Mon Jun 11 15:12:06 2012
@@ -32,7 +32,7 @@ import org.apache.http.conn.ConnectionRe
 import org.apache.http.conn.ManagedClientConnection;
 
 /**
- * Interface to be implemented by any object that wishes to be notified of request execution 
+ * Interface to be implemented by any object that wishes to be notified of request execution
  * events.
  *
  * @since 4.3
@@ -40,7 +40,7 @@ import org.apache.http.conn.ManagedClien
 public interface HttpExecutionAware {
 
     boolean isAborted();
-    
+
     /**
      * Sets the {@link ClientConnectionRequest} callback that can be
      * used to abort a long-lived request for a connection.

Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainRequestExecutor.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainRequestExecutor.java?rev=1348893&r1=1348892&r2=1348893&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainRequestExecutor.java (original)
+++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainRequestExecutor.java Mon Jun 11 15:12:06 2012
@@ -191,9 +191,37 @@ public class MainRequestExecutor impleme
 
         Object userToken = context.getAttribute(ClientContext.USER_TOKEN);
 
-        ManagedClientConnection managedConn = null;
+        ClientConnectionRequest connRequest = connManager.requestConnection(route, userToken);
+        if (execAware != null) {
+            if (execAware.isAborted()) {
+                connRequest.abortRequest();
+                throw new RequestAbortedException("Request aborted");
+            } else {
+                execAware.setConnectionRequest(connRequest);
+            }
+        }
+
+        ManagedClientConnection managedConn;
+        try {
+            long timeout = HttpClientParams.getConnectionManagerTimeout(params);
+            managedConn = connRequest.getConnection(timeout, TimeUnit.MILLISECONDS);
+        } catch(InterruptedException interrupted) {
+            throw new RequestAbortedException("Request aborted", interrupted);
+        }
+
+        context.setAttribute(ExecutionContext.HTTP_CONNECTION, managedConn);
+
+        if (HttpConnectionParams.isStaleCheckingEnabled(params)) {
+            // validate connection
+            if (managedConn.isOpen()) {
+                this.log.debug("Stale connection check");
+                if (managedConn.isStale()) {
+                    this.log.debug("Stale connection detected");
+                    managedConn.close();
+                }
+            }
+        }
 
-        boolean reuse = false;
         try {
             HttpResponse response = null;
             for (int execCount = 1;; execCount++) {
@@ -203,38 +231,6 @@ public class MainRequestExecutor impleme
                             "with a non-repeatable request entity.");
                 }
 
-                // Allocate connection if needed
-                if (managedConn == null) {
-                    ClientConnectionRequest connRequest = connManager.requestConnection(
-                            route, userToken);
-                    if (execAware != null) {
-                        if (execAware.isAborted()) {
-                            connRequest.abortRequest();
-                            throw new RequestAbortedException("Request aborted");
-                        } else {
-                            execAware.setConnectionRequest(connRequest);
-                        }
-                    }
-
-                    long timeout = HttpClientParams.getConnectionManagerTimeout(params);
-                    try {
-                        managedConn = connRequest.getConnection(timeout, TimeUnit.MILLISECONDS);
-                    } catch(InterruptedException interrupted) {
-                        throw new RequestAbortedException("Request aborted", interrupted);
-                    }
-
-                    if (HttpConnectionParams.isStaleCheckingEnabled(params)) {
-                        // validate connection
-                        if (managedConn.isOpen()) {
-                            this.log.debug("Stale connection check");
-                            if (managedConn.isStale()) {
-                                this.log.debug("Stale connection detected");
-                                managedConn.close();
-                            }
-                        }
-                    }
-                }
-
                 if (execAware != null) {
                     if (execAware.isAborted()) {
                         managedConn.releaseConnection();
@@ -251,8 +247,6 @@ public class MainRequestExecutor impleme
                     managedConn.setSocketTimeout(HttpConnectionParams.getSoTimeout(params));
                 }
 
-                context.setAttribute(ExecutionContext.HTTP_CONNECTION, managedConn);
-
                 try {
                     establishRoute(proxyAuthState, managedConn, route, context);
                 } catch (TunnelRefusedException ex) {
@@ -266,7 +260,7 @@ public class MainRequestExecutor impleme
                 if (execAware != null && execAware.isAborted()) {
                     throw new RequestAbortedException("Request aborted");
                 }
-                
+
                 String userinfo = request.getURI().getUserInfo();
                 if (userinfo != null) {
                     targetAuthState.update(
@@ -276,7 +270,7 @@ public class MainRequestExecutor impleme
                 if (this.log.isDebugEnabled()) {
                     this.log.debug("Executing request " + request.getRequestLine());
                 }
-                
+
                 // Run request protocol interceptors
                 requestExec.preProcess(request, httpProcessor, context);
 
@@ -287,8 +281,7 @@ public class MainRequestExecutor impleme
                 requestExec.postProcess(response, httpProcessor, context);
 
                 // The connection is in or can be brought to a re-usable state.
-                reuse = reuseStrategy.keepAlive(response, context);
-                if (reuse) {
+                if (reuseStrategy.keepAlive(response, context)) {
                     // Set the idle duration of this connection
                     long duration = keepAliveStrategy.getKeepAliveDuration(response, context);
                     if (this.log.isDebugEnabled()) {
@@ -301,17 +294,19 @@ public class MainRequestExecutor impleme
                         this.log.debug("Connection can be kept alive " + s);
                     }
                     managedConn.setIdleDuration(duration, TimeUnit.MILLISECONDS);
+                    managedConn.markReusable();
+                } else {
+                    managedConn.unmarkReusable();
                 }
 
                 if (needAuthentication(
                         targetAuthState, proxyAuthState, route, request, response, context)) {
-                    if (reuse) {
+                    if (managedConn.isMarkedReusable()) {
                         // Make sure the response body is fully consumed, if present
                         HttpEntity entity = response.getEntity();
                         EntityUtils.consume(entity);
                         // entity consumed above is not an auto-release entity,
                         // need to mark the connection re-usable explicitly
-                        managedConn.markReusable();
                     } else {
                         managedConn.close();
                         if (proxyAuthState.getState() == AuthProtocolState.SUCCESS
@@ -334,32 +329,26 @@ public class MainRequestExecutor impleme
                 }
             }
 
-            if (managedConn != null) {
-                if (userToken == null) {
-                    userToken = userTokenHandler.getUserToken(context);
-                    context.setAttribute(ClientContext.USER_TOKEN, userToken);
-                }
-                if (userToken != null) {
-                    managedConn.setState(userToken);
-                }
+            if (userToken == null) {
+                userToken = userTokenHandler.getUserToken(context);
+                context.setAttribute(ClientContext.USER_TOKEN, userToken);
+            }
+            if (userToken != null) {
+                managedConn.setState(userToken);
             }
 
             // check for entity, release connection if possible
             HttpEntity entity = response.getEntity();
             if (entity == null || !entity.isStreaming()) {
                 // connection not needed and (assumed to be) in re-usable state
-                if (reuse) {
-                    managedConn.markReusable();
-                }
                 try {
                     managedConn.releaseConnection();
                 } catch(IOException ex) {
                     this.log.debug("IOException releasing connection", ex);
                 }
-                managedConn = null;
             } else {
                 // install an auto-release entity
-                entity = new ManagedEntity(entity, managedConn, reuse);
+                entity = new ManagedEntity(entity, managedConn, execAware);
                 response.setEntity(entity);
             }
 
@@ -622,15 +611,13 @@ public class MainRequestExecutor impleme
      * {@link #execute execute} during exception handling.
      */
     private void abortConnection(final ManagedClientConnection managedConn) {
-        if (managedConn != null) {
-            // we got here as the result of an exception
-            // no response will be returned, release the connection
-            try {
-                managedConn.abortConnection();
-            } catch (IOException ex) {
-                if (this.log.isDebugEnabled()) {
-                    this.log.debug(ex.getMessage(), ex);
-                }
+        // we got here as the result of an exception
+        // no response will be returned, release the connection
+        try {
+            managedConn.abortConnection();
+        } catch (IOException ex) {
+            if (this.log.isDebugEnabled()) {
+                this.log.debug(ex.getMessage(), ex);
             }
         }
     }

Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/ManagedEntity.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/ManagedEntity.java?rev=1348893&r1=1348892&r2=1348893&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/ManagedEntity.java (original)
+++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/ManagedEntity.java Mon Jun 11 15:12:06 2012
@@ -33,6 +33,7 @@ import java.io.OutputStream;
 import java.net.SocketException;
 
 import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.client.methods.HttpExecutionAware;
 import org.apache.http.conn.EofSensorInputStream;
 import org.apache.http.conn.EofSensorWatcher;
 import org.apache.http.conn.ManagedClientConnection;
@@ -50,15 +51,15 @@ import org.apache.http.util.EntityUtils;
 class ManagedEntity extends HttpEntityWrapper implements EofSensorWatcher {
 
     private ManagedClientConnection managedConn;
-    private final boolean attemptReuse;
+    private HttpExecutionAware execAware;
 
     public ManagedEntity(
             final HttpEntity entity,
             final ManagedClientConnection managedConn,
-            boolean reuse) {
+            final HttpExecutionAware execAware) {
         super(entity);
         this.managedConn = managedConn;
-        this.attemptReuse = reuse;
+        this.execAware = execAware;
     }
 
     @Override
@@ -76,7 +77,7 @@ class ManagedEntity extends HttpEntityWr
             return;
         }
         try {
-            if (this.attemptReuse) {
+            if (this.managedConn.isMarkedReusable()) {
                 // this will not trigger a callback from EofSensorInputStream
                 EntityUtils.consume(this.wrappedEntity);
                 releaseConnection();
@@ -94,19 +95,16 @@ class ManagedEntity extends HttpEntityWr
 
     @Override
     public void writeTo(final OutputStream outstream) throws IOException {
-        super.writeTo(outstream);
+        this.wrappedEntity.writeTo(outstream);
         ensureConsumed();
     }
 
     public boolean eofDetected(final InputStream wrapped) throws IOException {
         try {
-            if (this.attemptReuse && (this.managedConn != null)) {
-                // there may be some cleanup required, such as
-                // reading trailers after the response body:
-                wrapped.close();
-                this.managedConn.markReusable();
-                releaseConnection();
-            }
+            // there may be some cleanup required, such as
+            // reading trailers after the response body:
+            wrapped.close();
+            releaseConnection();
         } finally {
             cleanup();
         }
@@ -115,18 +113,15 @@ class ManagedEntity extends HttpEntityWr
 
     public boolean streamClosed(InputStream wrapped) throws IOException {
         try {
-            if (this.attemptReuse && (this.managedConn != null)) {
-                boolean valid = this.managedConn.isOpen();
-                // this assumes that closing the stream will
-                // consume the remainder of the response body:
-                try {
-                    wrapped.close();
-                    this.managedConn.markReusable();
-                    releaseConnection();
-                } catch (SocketException ex) {
-                    if (valid) {
-                        throw ex;
-                    }
+            boolean aborted = this.execAware != null && this.execAware.isAborted();
+            // this assumes that closing the stream will
+            // consume the remainder of the response body:
+            try {
+                wrapped.close();
+                releaseConnection();
+            } catch (SocketException ex) {
+                if (!aborted) {
+                    throw ex;
                 }
             }
         } finally {
@@ -152,5 +147,6 @@ class ManagedEntity extends HttpEntityWr
             this.managedConn.abortConnection();
             this.managedConn = null;
         }
+        this.execAware = null;
     }
 }