Package org.apache.geronimo.connector.outbound

Source Code of org.apache.geronimo.connector.outbound.SinglePoolMatchAllConnectionInterceptor

/**
*
* Copyright 2003-2004 The Apache Software Foundation
*
*  Licensed 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.
*/

package org.apache.geronimo.connector.outbound;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.resource.ResourceException;
import javax.resource.spi.ManagedConnection;
import javax.resource.spi.ManagedConnectionFactory;

import EDU.oswego.cs.dl.util.concurrent.FIFOSemaphore;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* This pool is the most spec-compliant pool.  It can be used by itself with no partitioning.
* It is apt to be the slowest pool.
* For each connection request, it synchronizes access to the pool and asks the
* ManagedConnectionFactory for a match from among all managed connections.  If none is found,
* it may discard a random existing connection, and creates a new connection.
*
* @version $Revision: 1.2 $ $Date: 2004/05/24 19:10:34 $
*/
public class SinglePoolMatchAllConnectionInterceptor implements ConnectionInterceptor {

    private static Log log = LogFactory.getLog(SinglePoolMatchAllConnectionInterceptor.class.getName());


    private final ConnectionInterceptor next;

    private FIFOSemaphore permits;

    private HashMap pool;

    private int maxSize;

    private int blockingTimeout;
    private int actualConnections = 0;

    public SinglePoolMatchAllConnectionInterceptor(
            final ConnectionInterceptor next,
            int maxSize,
            int blockingTimeout) {
        this.next = next;
        this.maxSize = maxSize;
        this.blockingTimeout = blockingTimeout;
        permits = new FIFOSemaphore(maxSize);
        pool = new HashMap(maxSize);
    }

    public void getConnection(ConnectionInfo connectionInfo) throws ResourceException {
        ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
        if (mci.getManagedConnection() != null) {
            return;
        }
        ManagedConnectionFactory managedConnectionFactory = mci.getManagedConnectionFactory();
        try {
            if (permits.attempt(blockingTimeout)) {
                synchronized (pool) {
                    try {
                        if (!pool.isEmpty()) {
                            ManagedConnection matchedMC =
                                    managedConnectionFactory
                                    .matchManagedConnections(
                                            pool.keySet(),
                                            mci.getSubject(),
                                            mci.getConnectionRequestInfo());
                            if (matchedMC != null) {
                                connectionInfo.setManagedConnectionInfo((ManagedConnectionInfo) pool.get(matchedMC));
                                if (log.isTraceEnabled()) {
                                    log.trace("Returning pooled connection " + connectionInfo.getManagedConnectionInfo());
                                }
                                return;
                            }
                            //matching failed or pool is empty
                            //if pool is at maximum size, pick a cx to kill
                            if (actualConnections == maxSize) {
                                Iterator iterator = pool.entrySet().iterator();
                                ManagedConnectionInfo kill = (ManagedConnectionInfo) ((Map.Entry) iterator.next()).getValue();
                                iterator.remove();
                                ConnectionInfo killInfo = new ConnectionInfo(kill);
                                returnConnection(killInfo, ConnectionReturnAction.DESTROY);
                            }
                            next.getConnection(connectionInfo);
                            actualConnections++;
                            if (log.isTraceEnabled()) {
                                log.trace("Returning new connection " + connectionInfo.getManagedConnectionInfo());
                            }
                            return;
                        }
                    } catch (ResourceException e) {
                        //something is wrong: rethrow, release permit
                        permits.release();
                        throw e;
                    }
                }
            } else {
                throw new ResourceException(
                        "No ManagedConnections available "
                        + "within configured blocking timeout ( "
                        + blockingTimeout
                        + " [ms] )");

            } // end of else

        } catch (InterruptedException ie) {
            throw new ResourceException("Interrupted while requesting permit!");
        } // end of try-catch
    }

    public void returnConnection(
            ConnectionInfo connectionInfo,
            ConnectionReturnAction connectionReturnAction) {
        if (log.isTraceEnabled()) {
            log.trace("returning connection" + connectionInfo.getConnectionHandle());
        }
        boolean wasInPool = false;
        ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
        if (connectionReturnAction == ConnectionReturnAction.DESTROY) {
            synchronized (pool) {
                wasInPool = (pool.remove(mci.getManagedConnection()) != null);
            }
        } else {
            if (mci.hasConnectionHandles()) {
                return;
            }
        } // end of else

        ManagedConnection mc = mci.getManagedConnection();
        try {
            mc.cleanup();
        } catch (ResourceException e) {
            connectionReturnAction = ConnectionReturnAction.DESTROY;
        }

        if (connectionReturnAction == ConnectionReturnAction.DESTROY) {
            actualConnections--;
            next.returnConnection(connectionInfo, connectionReturnAction);
        } else {
            synchronized (pool) {
                mci.setLastUsed(System.currentTimeMillis());
                pool.put(mci.getManagedConnection(), mci);
            }
        }
        if (!wasInPool) {
            permits.release();
        }
    }

}
TOP

Related Classes of org.apache.geronimo.connector.outbound.SinglePoolMatchAllConnectionInterceptor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.