FileDocCategorySizeDatePackage
SingleClientConnManager.javaAPI DocAndroid 1.5 API14210Wed May 06 22:41:10 BST 2009org.apache.http.impl.conn

SingleClientConnManager

public class SingleClientConnManager extends Object implements ClientConnectionManager
A connection "manager" for a single connection. This manager is good only for single-threaded use. Allocation always returns the connection immediately, even if it has not been released after the previous allocation. In that case, a {@link #MISUSE_MESSAGE warning} is logged and the previously issued connection is revoked.

This class is derived from SimpleHttpConnectionManager in HttpClient 3. See there for original authors.

author
Roland Weber
author
Michael Becke
version
$Revision: 673450 $
since
4.0

Fields Summary
private final Log
log
public static final String
MISUSE_MESSAGE
The message to be logged on multiple allocation.
protected SchemeRegistry
schemeRegistry
The schemes supported by this connection manager.
protected ClientConnectionOperator
connOperator
The operator for opening and updating connections.
protected PoolEntry
uniquePoolEntry
The one and only entry in this pool.
protected ConnAdapter
managedConn
The currently issued managed connection, if any.
protected long
lastReleaseTime
The time of the last connection release, or -1.
protected long
connectionExpiresTime
The time the last released connection expires and shouldn't be reused.
protected boolean
alwaysShutDown
Whether the connection should be shut down on release.
protected volatile boolean
isShutDown
Indicates whether this connection manager is shut down.
Constructors Summary
public SingleClientConnManager(HttpParams params, SchemeRegistry schreg)
Creates a new simple connection manager.

param
params the parameters for this manager
param
schreg the scheme registry, or null for the default registry





                                                        
      
                                     

        if (schreg == null) {
            throw new IllegalArgumentException
                ("Scheme registry must not be null.");
        }
        this.schemeRegistry  = schreg;
        this.connOperator    = createConnectionOperator(schreg);
        this.uniquePoolEntry = new PoolEntry();
        this.managedConn     = null;
        this.lastReleaseTime = -1L;
        this.alwaysShutDown  = false; //@@@ from params? as argument?
        this.isShutDown      = false;

    
Methods Summary
protected final voidassertStillUp()
Asserts that this manager is not shut down.

throws
IllegalStateException if this manager is shut down


        if (this.isShutDown)
            throw new IllegalStateException("Manager is shut down.");
    
public voidcloseExpiredConnections()

        if(System.currentTimeMillis() >= connectionExpiresTime) {
            closeIdleConnections(0, TimeUnit.MILLISECONDS);
        }
    
public voidcloseIdleConnections(long idletime, java.util.concurrent.TimeUnit tunit)

        assertStillUp();

        // idletime can be 0 or negative, no problem there
        if (tunit == null) {
            throw new IllegalArgumentException("Time unit must not be null.");
        }

        if ((managedConn == null) && uniquePoolEntry.connection.isOpen()) {
            final long cutoff =
                System.currentTimeMillis() - tunit.toMillis(idletime);
            if (lastReleaseTime <= cutoff) {
                try {
                    uniquePoolEntry.close();
                } catch (IOException iox) {
                    // ignore
                    log.debug("Problem closing idle connection.", iox);
                }
            }
        }
    
protected org.apache.http.conn.ClientConnectionOperatorcreateConnectionOperator(org.apache.http.conn.scheme.SchemeRegistry schreg)
Hook for creating the connection operator. It is called by the constructor. Derived classes can override this method to change the instantiation of the operator. The default implementation here instantiates {@link DefaultClientConnectionOperator DefaultClientConnectionOperator}.

param
schreg the scheme registry to use, or null
return
the connection operator to use


        return new DefaultClientConnectionOperator(schreg);
    
protected voidfinalize()

        shutdown();
        super.finalize();
    
public org.apache.http.conn.ManagedClientConnectiongetConnection(org.apache.http.conn.routing.HttpRoute route, java.lang.Object state)
Obtains a connection. This method does not block.

param
route where the connection should point to
return
a connection that can be used to communicate along the given route


        if (route == null) {
            throw new IllegalArgumentException("Route may not be null.");
        }
        assertStillUp();

        if (log.isDebugEnabled()) {
            log.debug("Get connection for route " + route);
        }

        if (managedConn != null)
            revokeConnection();

        // check re-usability of the connection
        boolean recreate = false;
        boolean shutdown = false;
        
        // Kill the connection if it expired.
        closeExpiredConnections();
        
        if (uniquePoolEntry.connection.isOpen()) {
            RouteTracker tracker = uniquePoolEntry.tracker;
            shutdown = (tracker == null || // can happen if method is aborted
                        !tracker.toRoute().equals(route));
        } else {
            // If the connection is not open, create a new PoolEntry,
            // as the connection may have been marked not reusable,
            // due to aborts -- and the PoolEntry should not be reused
            // either.  There's no harm in recreating an entry if
            // the connection is closed.
            recreate = true;
        }

        if (shutdown) {
            recreate = true;
            try {
                uniquePoolEntry.shutdown();
            } catch (IOException iox) {
                log.debug("Problem shutting down connection.", iox);
            }
        }
        
        if (recreate)
            uniquePoolEntry = new PoolEntry();

        managedConn = new ConnAdapter(uniquePoolEntry, route);

        return managedConn;
    
public org.apache.http.conn.scheme.SchemeRegistrygetSchemeRegistry()

        return this.schemeRegistry;
    
public voidreleaseConnection(org.apache.http.conn.ManagedClientConnection conn, long validDuration, java.util.concurrent.TimeUnit timeUnit)

        assertStillUp();

        if (!(conn instanceof ConnAdapter)) {
            throw new IllegalArgumentException
                ("Connection class mismatch, " +
                 "connection not obtained from this manager.");
        }
        
        if (log.isDebugEnabled()) {
            log.debug("Releasing connection " + conn);
        }

        ConnAdapter sca = (ConnAdapter) conn;
        if (sca.poolEntry == null)
            return; // already released
        ClientConnectionManager manager = sca.getManager();
        if (manager != null && manager != this) {
            throw new IllegalArgumentException
                ("Connection not obtained from this manager.");
        }

        try {
            // make sure that the response has been read completely
            if (sca.isOpen() && (this.alwaysShutDown ||
                                 !sca.isMarkedReusable())
                ) {
                if (log.isDebugEnabled()) {
                    log.debug
                        ("Released connection open but not reusable.");
                }

                // make sure this connection will not be re-used
                // we might have gotten here because of a shutdown trigger
                // shutdown of the adapter also clears the tracked route
                sca.shutdown();
            }
        } catch (IOException iox) {
            //@@@ log as warning? let pass?
            if (log.isDebugEnabled())
                log.debug("Exception shutting down released connection.",
                          iox);
        } finally {
            sca.detach();
            managedConn = null;
            lastReleaseTime = System.currentTimeMillis();
            if(validDuration > 0)
                connectionExpiresTime = timeUnit.toMillis(validDuration) + lastReleaseTime;
            else
                connectionExpiresTime = Long.MAX_VALUE;
        }
    
public final org.apache.http.conn.ClientConnectionRequestrequestConnection(org.apache.http.conn.routing.HttpRoute route, java.lang.Object state)

        
        return new ClientConnectionRequest() {
            
            public void abortRequest() {
                // Nothing to abort, since requests are immediate.
            }
            
            public ManagedClientConnection getConnection(
                    long timeout, TimeUnit tunit) {
                return SingleClientConnManager.this.getConnection(
                        route, state);
            }
            
        };
    
protected voidrevokeConnection()
Revokes the currently issued connection. The adapter gets disconnected, the connection will be shut down.

        if (managedConn == null)
            return;

        log.warn(MISUSE_MESSAGE);

        managedConn.detach();

        try {
            uniquePoolEntry.shutdown();
        } catch (IOException iox) {
            // ignore
            log.debug("Problem while shutting down connection.", iox);
        }
    
public voidshutdown()


        this.isShutDown = true;

        if (managedConn != null)
            managedConn.detach();

        try {
            if (uniquePoolEntry != null) // and connection open?
                uniquePoolEntry.shutdown();
        } catch (IOException iox) {
            // ignore
            log.debug("Problem while shutting down manager.", iox);
        } finally {
            uniquePoolEntry = null;
        }