HTTPCLIENT-652:

* Reverting most of my previous changes. Passing a state object to the connection manager when trying to obtain a connection is completely pointless, as usually connection state information becomes available only after the connection has been established, for instance, after having been challenged by an authenticating server. Therefore, it is necessary to be able to set a state object on an active connection
* added method to set state object on ManagedClientConnection

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@646918 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2008-04-10 18:30:12 +00:00
parent 8ff6eedd9e
commit 824b785a99
16 changed files with 79 additions and 148 deletions

View File

@ -229,5 +229,11 @@ public interface ManagedClientConnection extends
boolean isMarkedReusable()
;
void setState(Object state)
;
boolean isStateful()
;
} // interface ManagedClientConnection

View File

@ -75,7 +75,10 @@ public abstract class AbstractPoolEntry {
//@@@ currently accessed from connection manager(s) as attribute
//@@@ avoid that, derived classes should decide whether update is allowed
//@@@ SCCM: yes, TSCCM: no
protected volatile ConnRoute route;
protected volatile HttpRoute route;
/** Connection state object */
protected volatile Object state;
/** The tracked route, or <code>null</code> before tracking starts. */
protected volatile RouteTracker tracker;
@ -89,7 +92,7 @@ public abstract class AbstractPoolEntry {
* or <code>null</code>
*/
protected AbstractPoolEntry(OperatedClientConnection occ,
ConnRoute route) {
HttpRoute route) {
this.connection = occ;
this.route = route;
this.tracker = null;

View File

@ -170,5 +170,16 @@ public abstract class AbstractPooledConnAdapter extends AbstractClientConnAdapte
}
}
// non-javadoc, see interface ManagedClientConnection
public boolean isStateful() {
assertAttached();
return poolEntry.state != null;
}
// non-javadoc, see interface ManagedClientConnection
public void setState(final Object state) {
poolEntry.state = state;
}
} // class AbstractPooledConnAdapter

View File

@ -1,98 +0,0 @@
/*
* $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 org.apache.http.conn.routing.HttpRoute;
import org.apache.http.util.LangUtils;
/**
* A route for {@link ManagedClientConnection} along with the state information
* associated with that connection.
*
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
*/
public class ConnRoute {
private final HttpRoute route;
private final Object state;
public ConnRoute(final HttpRoute route, final Object state) {
super();
if (route == null) {
throw new IllegalArgumentException("HTTP route may not be null");
}
this.route = route;
this.state = state;
}
public HttpRoute getRoute() {
return this.route;
}
public Object getState() {
return this.state;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) return false;
if (this == obj) return true;
if (obj instanceof ConnRoute) {
ConnRoute that = (ConnRoute) obj;
return this.route.equals(that.route)
&& LangUtils.equals(this.state, that.state);
} else {
return false;
}
}
@Override
public int hashCode() {
int hash = LangUtils.HASH_SEED;
hash = LangUtils.hashCode(hash, this.route);
hash = LangUtils.hashCode(hash, this.state);
return hash;
}
@Override
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append(this.route);
if (this.state != null) {
buffer.append(" [");
buffer.append(this.state);
buffer.append("]");
}
return buffer.toString();
}
}

View File

@ -239,7 +239,7 @@ public class SingleClientConnManager implements ClientConnectionManager {
}
}
managedConn = new ConnAdapter(uniquePoolEntry, new ConnRoute(route, state));
managedConn = new ConnAdapter(uniquePoolEntry, route);
return managedConn;
}
@ -420,11 +420,12 @@ public class SingleClientConnManager implements ClientConnectionManager {
* @param entry the pool entry for the connection being wrapped
* @param plan the planned route for this connection
*/
protected ConnAdapter(PoolEntry entry, ConnRoute route) {
protected ConnAdapter(PoolEntry entry, HttpRoute route) {
super(SingleClientConnManager.this, entry);
markReusable();
entry.route = route;
}
}

View File

@ -47,9 +47,9 @@ import org.apache.http.conn.ClientConnectionOperator;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.conn.OperatedClientConnection;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.params.HttpParams;
import org.apache.http.impl.conn.IdleConnectionHandler;
import org.apache.http.impl.conn.ConnRoute;
@ -209,10 +209,14 @@ public abstract class AbstractConnPool implements RefQueueHandler {
* if the calling thread was interrupted
*/
public final
BasicPoolEntry getEntry(ConnRoute route, long timeout, TimeUnit tunit,
ClientConnectionOperator operator)
throws ConnectionPoolTimeoutException, InterruptedException {
return newPoolEntryRequest().getPoolEntry(route, timeout, tunit, operator);
BasicPoolEntry getEntry(
HttpRoute route,
Object state,
long timeout,
TimeUnit tunit,
ClientConnectionOperator operator)
throws ConnectionPoolTimeoutException, InterruptedException {
return newPoolEntryRequest().getPoolEntry(route, state, timeout, tunit, operator);
}
/**
@ -247,7 +251,7 @@ public abstract class AbstractConnPool implements RefQueueHandler {
//@@@ flag in the BasicPoolEntryRef, to be reset when freed?
final boolean lost = issuedConnections.remove(ref);
if (lost) {
final ConnRoute route =
final HttpRoute route =
((BasicPoolEntryRef)ref).getRoute();
if (LOG.isDebugEnabled()) {
LOG.debug("Connection garbage collected. " + route);
@ -274,7 +278,7 @@ public abstract class AbstractConnPool implements RefQueueHandler {
*
* @param route the route of the pool entry that was lost
*/
protected abstract void handleLostEntry(ConnRoute route)
protected abstract void handleLostEntry(HttpRoute route)
;

View File

@ -35,8 +35,8 @@ import java.lang.ref.ReferenceQueue;
import org.apache.http.conn.OperatedClientConnection;
import org.apache.http.conn.ClientConnectionOperator;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.impl.conn.AbstractPoolEntry;
import org.apache.http.impl.conn.ConnRoute;
@ -67,7 +67,7 @@ public class BasicPoolEntry extends AbstractPoolEntry {
* or <code>null</code>
*/
public BasicPoolEntry(ClientConnectionOperator op,
ConnRoute route,
HttpRoute route,
ReferenceQueue<Object> queue) {
//@@@ create connection in base? or delay creation until needed?
super(op.createConnection(), route);
@ -92,7 +92,7 @@ public class BasicPoolEntry extends AbstractPoolEntry {
return super.connection;
}
protected final ConnRoute getPlannedRoute() {
protected final HttpRoute getPlannedRoute() {
return super.route;
}

View File

@ -34,7 +34,7 @@ package org.apache.http.impl.conn.tsccm;
import java.lang.ref.WeakReference;
import java.lang.ref.ReferenceQueue;
import org.apache.http.impl.conn.ConnRoute;
import org.apache.http.conn.routing.HttpRoute;
@ -46,7 +46,7 @@ import org.apache.http.impl.conn.ConnRoute;
public class BasicPoolEntryRef extends WeakReference<BasicPoolEntry> {
/** The planned route of the entry. */
private final ConnRoute route;
private final HttpRoute route;
/**
@ -72,7 +72,7 @@ public class BasicPoolEntryRef extends WeakReference<BasicPoolEntry> {
*
* @return the planned route
*/
public final ConnRoute getRoute() {
public final HttpRoute getRoute() {
return this.route;
}

View File

@ -46,7 +46,6 @@ import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ClientConnectionOperator;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.conn.params.HttpConnectionManagerParams;
import org.apache.http.impl.conn.ConnRoute;
@ -84,7 +83,7 @@ public class ConnPoolByRoute extends AbstractConnPool {
* Keys are of class {@link HttpRoute},
* values of class {@link RouteSpecificPool}.
*/
protected final Map<ConnRoute, RouteSpecificPool> routeToPool;
protected final Map<HttpRoute, RouteSpecificPool> routeToPool;
@ -128,8 +127,8 @@ public class ConnPoolByRoute extends AbstractConnPool {
*
* @return a map
*/
protected Map<ConnRoute,RouteSpecificPool> createRouteToPoolMap() {
return new HashMap<ConnRoute, RouteSpecificPool>();
protected Map<HttpRoute, RouteSpecificPool> createRouteToPoolMap() {
return new HashMap<HttpRoute, RouteSpecificPool>();
}
@ -141,7 +140,7 @@ public class ConnPoolByRoute extends AbstractConnPool {
*
* @return the new pool
*/
protected RouteSpecificPool newRouteSpecificPool(ConnRoute route) {
protected RouteSpecificPool newRouteSpecificPool(HttpRoute route) {
return new RouteSpecificPool(route);
}
@ -170,7 +169,7 @@ public class ConnPoolByRoute extends AbstractConnPool {
* @return the pool for the argument route,
* never <code>null</code> if <code>create</code> is <code>true</code>
*/
protected RouteSpecificPool getRoutePool(ConnRoute route,
protected RouteSpecificPool getRoutePool(HttpRoute route,
boolean create) {
RouteSpecificPool rospl = null;
@ -193,7 +192,7 @@ public class ConnPoolByRoute extends AbstractConnPool {
//@@@ consider alternatives for gathering statistics
public int getConnectionsInPool(ConnRoute route) {
public int getConnectionsInPool(HttpRoute route) {
try {
poolLock.lock();
@ -224,12 +223,13 @@ public class ConnPoolByRoute extends AbstractConnPool {
}
public BasicPoolEntry getPoolEntry(
ConnRoute route,
HttpRoute route,
Object state,
long timeout,
TimeUnit tunit,
ClientConnectionOperator operator)
throws InterruptedException, ConnectionPoolTimeoutException {
return getEntryBlocking(route, timeout, tunit, operator, aborter);
return getEntryBlocking(route, state, timeout, tunit, operator, aborter);
}
};
@ -256,14 +256,14 @@ public class ConnPoolByRoute extends AbstractConnPool {
* if the calling thread was interrupted
*/
protected BasicPoolEntry getEntryBlocking(
ConnRoute route,
HttpRoute route, Object state,
long timeout, TimeUnit tunit,
ClientConnectionOperator operator,
Aborter aborter)
throws ConnectionPoolTimeoutException, InterruptedException {
int maxHostConnections = HttpConnectionManagerParams
.getMaxConnectionsPerHost(this.params, route.getRoute());
.getMaxConnectionsPerHost(this.params, route);
int maxTotalConnections = HttpConnectionManagerParams
.getMaxTotalConnections(this.params);
@ -363,7 +363,7 @@ public class ConnPoolByRoute extends AbstractConnPool {
@Override
public void freeEntry(BasicPoolEntry entry) {
ConnRoute route = entry.getPlannedRoute();
HttpRoute route = entry.getPlannedRoute();
if (LOG.isDebugEnabled()) {
LOG.debug("Freeing connection. " + route);
}
@ -493,7 +493,7 @@ public class ConnPoolByRoute extends AbstractConnPool {
*/
protected void deleteEntry(BasicPoolEntry entry) {
ConnRoute route = entry.getPlannedRoute();
HttpRoute route = entry.getPlannedRoute();
if (LOG.isDebugEnabled()) {
LOG.debug("Deleting connection. " + route);
@ -546,7 +546,7 @@ public class ConnPoolByRoute extends AbstractConnPool {
// non-javadoc, see base class AbstractConnPool
@Override
protected void handleLostEntry(ConnRoute route) {
protected void handleLostEntry(HttpRoute route) {
try {
poolLock.lock();

View File

@ -35,7 +35,6 @@ import java.util.concurrent.TimeUnit;
import org.apache.http.conn.ClientConnectionOperator;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.impl.conn.ConnRoute;
/**
* Encapsulates a request for a {@link BasicPoolEntry}.
@ -62,7 +61,8 @@ public interface PoolEntryRequest {
* if the calling thread was interrupted
*/
BasicPoolEntry getPoolEntry(
ConnRoute route,
HttpRoute route,
Object state,
long timeout,
TimeUnit unit,
ClientConnectionOperator operator)

View File

@ -33,7 +33,7 @@ package org.apache.http.impl.conn.tsccm;
import java.util.Queue;
import java.util.LinkedList;
import org.apache.http.impl.conn.ConnRoute;
import org.apache.http.conn.routing.HttpRoute;
/**
@ -44,7 +44,7 @@ import org.apache.http.impl.conn.ConnRoute;
public class RouteSpecificPool {
/** The route this pool is for. */
protected final ConnRoute route;
protected final HttpRoute route;
/**
* The list of free entries.
@ -65,7 +65,7 @@ public class RouteSpecificPool {
*
* @param r the route for which to pool
*/
public RouteSpecificPool(ConnRoute route) {
public RouteSpecificPool(HttpRoute route) {
this.route = route;
this.freeEntries = new LinkedList<BasicPoolEntry>();
this.waitingThreads = new LinkedList<WaitingThread>();
@ -78,7 +78,7 @@ public class RouteSpecificPool {
*
* @return the route
*/
public final ConnRoute getRoute() {
public final HttpRoute getRoute() {
return route;
}

View File

@ -45,7 +45,6 @@ import org.apache.http.conn.ManagedClientConnection;
import org.apache.http.conn.OperatedClientConnection;
import org.apache.http.params.HttpParams;
import org.apache.http.impl.conn.DefaultClientConnectionOperator;
import org.apache.http.impl.conn.ConnRoute;
@ -171,7 +170,7 @@ public class ThreadSafeClientConnManager
}
final BasicPoolEntry entry = poolRequest.getPoolEntry(
new ConnRoute(route, state), timeout, tunit, connOperator);
route, state, timeout, tunit, connOperator);
return new BasicPooledConnAdapter(ThreadSafeClientConnManager.this, entry);
}
@ -242,9 +241,9 @@ public class ThreadSafeClientConnManager
*
* @return the total number of pooled connections for that route
*/
public int getConnectionsInPool(HttpRoute route, Object state) {
public int getConnectionsInPool(HttpRoute route) {
return ((ConnPoolByRoute)connectionPool).getConnectionsInPool(
new ConnRoute(route, state));
route);
}

View File

@ -75,4 +75,11 @@ public class ClientConnAdapterMockup extends AbstractClientConnAdapter {
throw new UnsupportedOperationException("just a mockup");
}
public boolean isStateful() {
throw new UnsupportedOperationException("just a mockup");
}
public void setState(Object state) {
throw new UnsupportedOperationException("just a mockup");
}
}

View File

@ -406,13 +406,13 @@ public class TestTSCCMNoServer extends TestCase {
assertEquals("connectionsInPool",
mgr.getConnectionsInPool(), 1);
assertEquals("connectionsInPool(host)",
mgr.getConnectionsInPool(route, null), 1);
mgr.getConnectionsInPool(route), 1);
mgr.releaseConnection(conn);
assertEquals("connectionsInPool",
mgr.getConnectionsInPool(), 1);
assertEquals("connectionsInPool(host)",
mgr.getConnectionsInPool(route, null), 1);
mgr.getConnectionsInPool(route), 1);
// this implicitly deletes them
mgr.closeIdleConnections(0L, TimeUnit.MILLISECONDS);
@ -420,7 +420,7 @@ public class TestTSCCMNoServer extends TestCase {
assertEquals("connectionsInPool",
mgr.getConnectionsInPool(), 0);
assertEquals("connectionsInPool(host)",
mgr.getConnectionsInPool(route, null), 0);
mgr.getConnectionsInPool(route), 0);
mgr.shutdown();
}

View File

@ -50,7 +50,6 @@ import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.scheme.SocketFactory;
import org.apache.http.conn.ClientConnectionOperator;
import org.apache.http.impl.conn.DefaultClientConnectionOperator;
import org.apache.http.impl.conn.ConnRoute;
@ -114,13 +113,13 @@ public class TestDumbHelpers extends TestCase {
// expected
}
bpe = new BasicPoolEntry(ccop, new ConnRoute(route, null), null);
bpe = new BasicPoolEntry(ccop, route, null);
assertEquals ("wrong operator", ccop, bpe.getOperator());
assertEquals ("wrong route", route, bpe.getPlannedRoute().getRoute());
assertEquals ("wrong route", route, bpe.getPlannedRoute());
assertNotNull("missing ref", bpe.getWeakRef());
assertEquals("bad weak ref", bpe, bpe.getWeakRef().get());
assertEquals("bad ref route", route, bpe.getWeakRef().getRoute().getRoute());
assertEquals("bad ref route", route, bpe.getWeakRef().getRoute());
}

View File

@ -40,7 +40,6 @@ import junit.framework.TestSuite;
import org.apache.http.HttpHost;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.impl.conn.ConnRoute;
@ -84,7 +83,7 @@ public class TestWaitingThread extends TestCase {
assertNull ("thread from nowhere", wt.getThread());
HttpRoute route = new HttpRoute(TARGET);
RouteSpecificPool rospl = new RouteSpecificPool(new ConnRoute(route, null));
RouteSpecificPool rospl = new RouteSpecificPool(route);
wt = new WaitingThread(cnd, rospl);
assertEquals("wrong condition", cnd, wt.getCondition());
assertEquals("wrong pool", rospl, wt.getPool());