new pooled connection adapter, simplified SingleCCM

git-svn-id: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpclient/trunk@511477 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Roland Weber 2007-02-25 10:41:55 +00:00
parent 674c28015f
commit e96c1657a7
4 changed files with 210 additions and 133 deletions

View File

@ -72,7 +72,7 @@ import org.apache.http.conn.ClientConnectionManager;
*
* @since 4.0
*/
public abstract class AbstractClientConnectionAdapter
public abstract class AbstractClientConnAdapter
implements ManagedClientConnection {
/** The connection manager, if any. */
@ -93,8 +93,8 @@ public abstract class AbstractClientConnectionAdapter
* @param mgr the connection manager, or <code>null</code>
* @param conn the connection to wrap, or <code>null</code>
*/
protected AbstractClientConnectionAdapter(ClientConnectionManager mgr,
OperatedClientConnection conn) {
protected AbstractClientConnAdapter(ClientConnectionManager mgr,
OperatedClientConnection conn) {
connManager = mgr;
wrappedConnection = conn;
@ -272,4 +272,4 @@ public abstract class AbstractClientConnectionAdapter
connManager.releaseConnection(this);
}
} // class AbstractClientConnectionAdapter
} // class AbstractClientConnAdapter

View File

@ -0,0 +1,168 @@
/*
* $HeadURL$
* $Revision$
* $Date$
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.impl.conn;
import java.io.IOException;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import org.apache.http.conn.HttpRoute;
import org.apache.http.conn.ClientConnectionManager;
/**
* Abstract adapter from pool {@link AbstractPoolEntry entries} to
* {@link ManagedClientConnection managed} client connections.
* The connection in the pool entry is used to initialize the base class.
* In addition, methods to establish a route are delegated to the
* pool entry. {@link #shutdown shutdown} and {@link #close close}
* will clear the tracked route in the pool entry and call the
* respective method of the wrapped connection.
*
* @author <a href="mailto:rolandw at apache.org">Roland Weber</a>
*
*
* <!-- empty lines to avoid svn diff problems -->
* @version $Revision$ $Date$
*
* @since 4.0
*/
public abstract class AbstractPooledConnAdapter
extends AbstractClientConnAdapter {
/** The wrapped pool entry. */
protected AbstractPoolEntry poolEntry;
/**
* Creates a new connection adapter.
*
* @param manager the connection manager
* @param entry the pool entry for the connection being wrapped
* <!--
* @ param plan the planned route, which will be used
* to update the pool entry
* -->
*/
protected AbstractPooledConnAdapter(ClientConnectionManager manager,
AbstractPoolEntry entry
//, HttpRoute plan
) {
super(manager, entry.connection);
//entry.plannedRoute = plan;
this.poolEntry = entry;
}
/**
* Asserts that this adapter is still attached.
*
* @throws IllegalStateException
* if it is {@link #detach detach}ed
*/
protected final void assertAttached() {
if (poolEntry == null) {
throw new IllegalStateException("Adapter is detached.");
}
}
/**
* Detaches this adapter from the wrapped connection.
* This adapter becomes useless.
*/
protected void detach() {
wrappedConnection = null;
poolEntry = null;
}
// non-javadoc, see interface ManagedHttpConnection
public HttpRoute getRoute() {
assertAttached();
return (poolEntry.tracker == null) ?
null : poolEntry.tracker.toRoute();
}
// non-javadoc, see interface ManagedHttpConnection
public void open(HttpRoute route,
HttpContext context, HttpParams params)
throws IOException {
assertAttached();
poolEntry.open(route, context, params);
}
// non-javadoc, see interface ManagedHttpConnection
public void tunnelCreated(boolean secure, HttpParams params)
throws IOException {
assertAttached();
poolEntry.tunnelCreated(secure, params);
}
// non-javadoc, see interface ManagedHttpConnection
public void layerProtocol(HttpContext context, HttpParams params)
throws IOException {
assertAttached();
poolEntry.layerProtocol(context, params);
}
// non-javadoc, see interface HttpConnection
public void close() throws IOException {
if (poolEntry != null)
poolEntry.closing();
if (wrappedConnection != null) {
wrappedConnection.close();
}
}
// non-javadoc, see interface HttpConnection
public void shutdown() throws IOException {
if (poolEntry != null)
poolEntry.closing();
if (wrappedConnection != null) {
wrappedConnection.shutdown();
}
}
} // class AbstractPooledConnAdapter

View File

@ -215,13 +215,12 @@ public class SingleClientConnManager implements ClientConnectionManager {
// check re-usability of the connection
if (uniquePoolEntry.connection.isOpen()) {
final boolean shutdown =
(uniquePoolEntry.tracker == null) || // how could that happen?
!uniquePoolEntry.tracker.toRoute().equals(route);
((uniquePoolEntry.tracker == null) || // how could that happen?
!uniquePoolEntry.tracker.toRoute().equals(route));
if (shutdown) {
uniquePoolEntry.closing();
try {
uniquePoolEntry.connection.shutdown();
uniquePoolEntry.shutdown();
} catch (IOException iox) {
LOG.debug("Problem shutting down connection.", iox);
// create a new connection, just to be sure
@ -251,7 +250,7 @@ public class SingleClientConnManager implements ClientConnectionManager {
throw new IllegalArgumentException
("Connection not obtained from this manager.");
}
if (sca.wrappedConnection == null)
if (sca.poolEntry == null)
return; // already released
try {
@ -265,9 +264,6 @@ public class SingleClientConnManager implements ClientConnectionManager {
}
// 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.
// we might have gotten here because of a shutdown trigger
// shutdown of the adapter also clears the tracked route
sca.shutdown();
@ -292,9 +288,8 @@ public class SingleClientConnManager implements ClientConnectionManager {
if ((managedConn == null) && uniquePoolEntry.connection.isOpen()) {
final long cutoff = System.currentTimeMillis() - idletime;
if (lastReleaseTime <= cutoff) {
uniquePoolEntry.closing();
try {
uniquePoolEntry.connection.close();
uniquePoolEntry.close();
} catch (IOException iox) {
// ignore
LOG.debug("Problem closing idle connection.", iox);
@ -314,7 +309,7 @@ public class SingleClientConnManager implements ClientConnectionManager {
try {
if (uniquePoolEntry != null) // and connection open?
uniquePoolEntry.connection.shutdown();
uniquePoolEntry.shutdown();
} catch (IOException iox) {
// ignore
LOG.debug("Problem while shutting down manager.", iox);
@ -342,11 +337,7 @@ public class SingleClientConnManager implements ClientConnectionManager {
managedConn.detach();
try {
if (uniquePoolEntry.connection.isOpen()) {
uniquePoolEntry.closing();
uniquePoolEntry.connection.shutdown();
}
uniquePoolEntry.shutdown();
} catch (IOException iox) {
// ignore
LOG.debug("Problem while shutting down connection.", iox);
@ -361,7 +352,7 @@ public class SingleClientConnManager implements ClientConnectionManager {
//@@@ move to base class when TSCCM is cleaned up
/** The route for which this entry gets allocated. */
private HttpRoute plannedRoute;
protected HttpRoute plannedRoute;
/**
@ -369,7 +360,7 @@ public class SingleClientConnManager implements ClientConnectionManager {
*
* @param occ the underlying connection for this entry
*/
private PoolEntry(OperatedClientConnection occ) {
protected PoolEntry(OperatedClientConnection occ) {
super(occ);
}
@ -379,133 +370,51 @@ public class SingleClientConnManager implements ClientConnectionManager {
return SingleClientConnManager.this.connOperator;
}
/**
* Closes the connection in this pool entry.
*/
protected void close()
throws IOException {
closing();
if (connection.isOpen())
connection.close();
}
/**
* Shuts down the connection in this pool entry.
*/
protected void shutdown()
throws IOException {
closing();
if (connection.isOpen())
connection.shutdown();
}
} // class PoolEntry
/**
* The connection adapter used by this manager.
* <p><i>Refactoring pending!</i>
* This has a lot of common code with private classes
* <code>TrackingPoolEntry</code> and <code>HttpConnectionAdapter</code>
* in {@link ThreadSafeClientConnManager ThreadSafeClientConnManager}.
*/
protected class ConnAdapter
extends AbstractClientConnectionAdapter {
/** The wrapped pool entry. */
private PoolEntry poolEntry;
protected class ConnAdapter extends AbstractPooledConnAdapter {
/**
* Creates a new connection adapter.
*
* @param entry the pool entry for the connection being wrapped
* @param plan the planned route for this connection
*/
protected ConnAdapter(PoolEntry entry, HttpRoute plan) {
super(SingleClientConnManager.this, entry.connection);
super(SingleClientConnManager.this, entry);
super.markedReusable = true;
entry.plannedRoute = plan;
this.poolEntry = entry;
}
/**
* Asserts that this adapter is still attached.
*
* @throws IllegalStateException
* if it is {@link #detach detach}ed
*/
protected final void assertAttached() {
if (wrappedConnection == null) {
throw new IllegalStateException("Adapter is detached.");
}
}
/**
* Checks if the wrapped connection is still available.
*
* @return <code>true</code> if still available,
* <code>false</code> if {@link #detach detached}
*/
protected boolean hasConnection() {
return wrappedConnection != null;
}
/**
* Detaches this adapter from the wrapped connection.
* This adapter becomes useless.
*/
protected void detach() {
this.wrappedConnection = null;
}
// non-javadoc, see interface ManagedHttpConnection
public HttpRoute getRoute() {
assertAttached();
return (poolEntry.tracker == null) ?
null : poolEntry.tracker.toRoute();
}
// non-javadoc, see interface ManagedHttpConnection
public void open(HttpRoute route,
HttpContext context, HttpParams params)
throws IOException {
assertAttached();
poolEntry.open(route, context, params);
}
// non-javadoc, see interface ManagedHttpConnection
public void tunnelCreated(boolean secure, HttpParams params)
throws IOException {
assertAttached();
poolEntry.tunnelCreated(secure, params);
}
// non-javadoc, see interface ManagedHttpConnection
public void layerProtocol(HttpContext context, HttpParams params)
throws IOException {
assertAttached();
poolEntry.layerProtocol(context, params);
}
// non-javadoc, see interface HttpConnection
public void close() throws IOException {
if (poolEntry != null)
poolEntry.closing();
if (hasConnection()) {
wrappedConnection.close();
} else {
// do nothing
}
}
// non-javadoc, see interface HttpConnection
public void shutdown() throws IOException {
if (poolEntry != null)
poolEntry.closing();
if (hasConnection()) {
wrappedConnection.shutdown();
} else {
// do nothing
}
}
} // class ConnAdapter
}
} // class SingleClientConnManager

View File

@ -1146,7 +1146,7 @@ public class ThreadSafeClientConnManager
* can be {@link #detach detach}ed to prevent further use on release.
*/
private class HttpConnectionAdapter
extends AbstractClientConnectionAdapter {
extends AbstractClientConnAdapter {
/** The wrapped pool entry. */
private TrackingPoolEntry poolEntry;