reusability flag in ManagedClientConnection
git-svn-id: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpclient/trunk@508798 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
486dd14981
commit
1c10f5e392
|
@ -144,4 +144,52 @@ public interface ManagedClientConnection
|
|||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Marks this connection as being in a reusable communication state.
|
||||
* The checkpoints for reuseable communication states (in the absence
|
||||
* of pipelining) are before sending a request and after receiving
|
||||
* the response in it's entirety.
|
||||
* The connection will automatically clear the checkpoint when
|
||||
* used for communication. A call to this method indicates that
|
||||
* the next checkpoint has been reached.
|
||||
* <br/>
|
||||
* A reusable communication state is necessary but not sufficient
|
||||
* for the connection to be reused.
|
||||
* A {@link #getRoute route} mismatch, the connection being closed,
|
||||
* or other circumstances might prevent reuse.
|
||||
*/
|
||||
void markReusable()
|
||||
;
|
||||
|
||||
|
||||
/**
|
||||
* Marks this connection as not being in a reusable state.
|
||||
* This can be used immediately before releasing this connection
|
||||
* to prevent it's reuse. Reasons for preventing reuse include
|
||||
* error conditions and the evaluation of a
|
||||
* {@link org.apache.http.ConnectionReuseStrategy reuse strategy}.
|
||||
* <br/>
|
||||
* <b>Note:</b>
|
||||
* It is <i>not</i> necessary to call here before writing to
|
||||
* or reading from this connection. Communication attempts will
|
||||
* automatically unmark the state as non-reusable. It can then
|
||||
* be switched back using {@link #markReusable markReusable}.
|
||||
*/
|
||||
void unmarkReusable()
|
||||
;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates whether this connection is in a reusable communication state.
|
||||
* See {@link #markReusable markReusable} and
|
||||
* {@link #unmarkReusable unmarkReusable} for details.
|
||||
*
|
||||
* @return <code>true</code> if this connection is marked as being in
|
||||
* a reusable communication state,
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
boolean isMarkedReusable()
|
||||
;
|
||||
|
||||
|
||||
} // interface ManagedClientConnection
|
||||
|
|
|
@ -188,27 +188,6 @@ public class DefaultClientRequestDirector
|
|||
//@@@ how to handle CONNECT requests for tunnelling?
|
||||
//@@@ refuse to send external CONNECT via director? special handling?
|
||||
|
||||
//@@@ this check for secure connections is an ugly hack until the
|
||||
//@@@ director is changed to expect HttpRoute instead of HostConfig
|
||||
/*
|
||||
//@@@ the actual check should be whether the socket factory
|
||||
//@@@ for the target host scheme is a SecureSocketFactory
|
||||
HttpRoute route = null;
|
||||
{
|
||||
final boolean secure =
|
||||
!"http".equals(hostconf.getHost().getSchemeName());
|
||||
if (hostconf.getProxyHost() == null)
|
||||
route = new HttpRoute(hostconf.getHost(),
|
||||
hostconf.getLocalAddress(),
|
||||
secure);
|
||||
else
|
||||
route = new HttpRoute(hostconf.getHost(),
|
||||
hostconf.getLocalAddress(),
|
||||
hostconf.getProxyHost(),
|
||||
secure);
|
||||
} //@@@ end of ugly HostConfiguration -> HttpRoute conversion
|
||||
*/
|
||||
|
||||
//@@@ should the request parameters already be used below?
|
||||
//@@@ probably yes, but they're not linked yet
|
||||
//@@@ will linking above cause problems with linking in reqExec?
|
||||
|
@ -288,6 +267,7 @@ public class DefaultClientRequestDirector
|
|||
|
||||
HttpResponse connected =
|
||||
requestExec.execute(connect, managedConn, context);
|
||||
managedConn.markReusable();
|
||||
int status = connected.getStatusLine().getStatusCode();
|
||||
//@@@ log something about the response?
|
||||
|
||||
|
@ -422,21 +402,26 @@ public class DefaultClientRequestDirector
|
|||
if ((response == null) || (response.getEntity() == null) ||
|
||||
!response.getEntity().isStreaming()) {
|
||||
// connection not needed and assumed to be in re-usable state
|
||||
//@@@ evaluate connection re-use strategy, close if necessary
|
||||
//@@@ evaluate connection re-use strategy,
|
||||
//@@@ close and/or mark as non-reusable if necessary
|
||||
managedConn = null;
|
||||
mcc.markReusable();
|
||||
connManager.releaseConnection(mcc);
|
||||
}
|
||||
} else {
|
||||
// we got here as the result of an exception
|
||||
// no response will be returned, release the connection
|
||||
managedConn = null;
|
||||
//@@@ is the connection in a re-usable state?
|
||||
//@@@ is the connection in a re-usable state? consume response?
|
||||
//@@@ for now, just shut it down
|
||||
// Do not delegate this to the connection manager, can't
|
||||
// tell whether it would shut down or close gracefully.
|
||||
try {
|
||||
if (mcc.isOpen())
|
||||
mcc.shutdown();
|
||||
} catch (IOException ignore) {
|
||||
// can't allow exception while handling exception
|
||||
//@@@ log as debug or warning?
|
||||
}
|
||||
connManager.releaseConnection(mcc);
|
||||
}
|
||||
|
|
|
@ -52,6 +52,11 @@ import org.apache.http.conn.ManagedClientConnection;
|
|||
* by derived classes. Operations for querying the connection state
|
||||
* are delegated to the wrapped connection if there is one, or
|
||||
* return a default value if there is none.
|
||||
* <br/>
|
||||
* This adapter tracks the checkpoints for reusable communication states,
|
||||
* as indicated by {@link #markReusable markReusable} and queried by
|
||||
* {@link #isMarkedReusable isMarkedReusable}.
|
||||
* All send and receive operations will automatically clear the mark.
|
||||
*
|
||||
* @author <a href="mailto:rolandw at apache.org">Roland Weber</a>
|
||||
*
|
||||
|
@ -67,15 +72,21 @@ public abstract class AbstractClientConnectionAdapter
|
|||
/** The wrapped connection. */
|
||||
protected OperatedClientConnection wrappedConnection;
|
||||
|
||||
/** The reusability marker. */
|
||||
protected boolean markedReusable;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new connection adapter.
|
||||
* The adapter is initially <i>not</i>
|
||||
* {@link #isMarkedReusable marked} as reusable.
|
||||
*
|
||||
* @param conn the connection to wrap, or <code>null</code>
|
||||
*/
|
||||
protected AbstractClientConnectionAdapter(OperatedClientConnection conn) {
|
||||
|
||||
wrappedConnection = conn;
|
||||
markedReusable = false;
|
||||
|
||||
} // <constructor>
|
||||
|
||||
|
@ -133,6 +144,7 @@ public abstract class AbstractClientConnectionAdapter
|
|||
throws HttpException, IOException {
|
||||
|
||||
assertWrappedConn();
|
||||
markedReusable = false;
|
||||
wrappedConnection.receiveResponseEntity(response);
|
||||
}
|
||||
|
||||
|
@ -142,6 +154,7 @@ public abstract class AbstractClientConnectionAdapter
|
|||
throws HttpException, IOException {
|
||||
|
||||
assertWrappedConn();
|
||||
markedReusable = false;
|
||||
return wrappedConnection.receiveResponseHeader(params);
|
||||
}
|
||||
|
||||
|
@ -151,6 +164,7 @@ public abstract class AbstractClientConnectionAdapter
|
|||
throws HttpException, IOException {
|
||||
|
||||
assertWrappedConn();
|
||||
markedReusable = false;
|
||||
wrappedConnection.sendRequestEntity(request);
|
||||
}
|
||||
|
||||
|
@ -160,6 +174,7 @@ public abstract class AbstractClientConnectionAdapter
|
|||
throws HttpException, IOException {
|
||||
|
||||
assertWrappedConn();
|
||||
markedReusable = false;
|
||||
wrappedConnection.sendRequestHeader(request);
|
||||
}
|
||||
|
||||
|
@ -195,5 +210,19 @@ public abstract class AbstractClientConnectionAdapter
|
|||
return wrappedConnection.isSecure();
|
||||
}
|
||||
|
||||
// non-javadoc, see interface ManagedClientConnection
|
||||
public void markReusable() {
|
||||
markedReusable = true;
|
||||
}
|
||||
|
||||
// non-javadoc, see interface ManagedClientConnection
|
||||
public void unmarkReusable() {
|
||||
markedReusable = false;
|
||||
}
|
||||
|
||||
// non-javadoc, see interface ManagedClientConnection
|
||||
public boolean isMarkedReusable() {
|
||||
return markedReusable;
|
||||
}
|
||||
|
||||
} // class AbstractClientConnectionAdapter
|
||||
|
|
|
@ -360,9 +360,34 @@ public class ThreadSafeClientConnManager
|
|||
("Connection not obtained from this manager.");
|
||||
}
|
||||
|
||||
TrackingPoolEntry entry = hca.poolEntry;
|
||||
hca.detach();
|
||||
releasePoolEntry(entry);
|
||||
try {
|
||||
// make sure that the response has been read completely
|
||||
if (!hca.isMarkedReusable()) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Released connection not marked reusable.");
|
||||
}
|
||||
// In MTHCM, method releasePoolEntry below would call
|
||||
// SimpleHttpConnectionManager.finishLastResponse(conn);
|
||||
//@@@ consume response here or outside? (rolandw: outside)
|
||||
|
||||
// make sure this connection will not be re-used
|
||||
//@@@ Can we set some kind of flag before shutting down?
|
||||
//@@@ If shutdown throws an exception, we can't be sure
|
||||
//@@@ that the connection will consider itself closed.
|
||||
// be nice and call close() rather than shutdown()?
|
||||
// I'm not in a nice mood today. -rolandw-
|
||||
hca.shutdown();
|
||||
}
|
||||
} catch (IOException iox) {
|
||||
//@@@ log as warning? let pass?
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Exception shutting down released connection",
|
||||
iox);
|
||||
} finally {
|
||||
TrackingPoolEntry entry = hca.poolEntry;
|
||||
hca.detach();
|
||||
releasePoolEntry(entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -377,9 +402,6 @@ public class ThreadSafeClientConnManager
|
|||
if (entry == null)
|
||||
return;
|
||||
|
||||
// make sure that the response has been read completely
|
||||
System.out.println("@@@ should consume response and free connection");
|
||||
//@@@ SimpleHttpConnectionManager.finishLastResponse(conn);
|
||||
connectionPool.freeConnection(entry);
|
||||
}
|
||||
|
||||
|
@ -1295,6 +1317,7 @@ public class ThreadSafeClientConnManager
|
|||
protected HttpConnectionAdapter(TrackingPoolEntry entry) {
|
||||
super(entry.connection);
|
||||
poolEntry = entry;
|
||||
super.markedReusable = true;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue