Search in sources :

Example 6 with PooledObject

use of org.datanucleus.store.rdbms.datasource.dbcp2.pool2.PooledObject in project datanucleus-rdbms by datanucleus.

the class GenericKeyedObjectPool method evict.

/**
 * {@inheritDoc}
 * <p>
 * Successive activations of this method examine objects in keyed sub-pools
 * in sequence, cycling through the keys and examining objects in
 * oldest-to-youngest order within the keyed sub-pools.
 */
@Override
public void evict() throws Exception {
    assertOpen();
    if (getNumIdle() == 0) {
        return;
    }
    PooledObject<T> underTest = null;
    final EvictionPolicy<T> evictionPolicy = getEvictionPolicy();
    synchronized (evictionLock) {
        final EvictionConfig evictionConfig = new EvictionConfig(getMinEvictableIdleTimeMillis(), getSoftMinEvictableIdleTimeMillis(), getMinIdlePerKey());
        final boolean testWhileIdle = getTestWhileIdle();
        for (int i = 0, m = getNumTests(); i < m; i++) {
            if (evictionIterator == null || !evictionIterator.hasNext()) {
                if (evictionKeyIterator == null || !evictionKeyIterator.hasNext()) {
                    final List<K> keyCopy = new ArrayList<>();
                    final Lock readLock = keyLock.readLock();
                    readLock.lock();
                    try {
                        keyCopy.addAll(poolKeyList);
                    } finally {
                        readLock.unlock();
                    }
                    evictionKeyIterator = keyCopy.iterator();
                }
                while (evictionKeyIterator.hasNext()) {
                    evictionKey = evictionKeyIterator.next();
                    final ObjectDeque<T> objectDeque = poolMap.get(evictionKey);
                    if (objectDeque == null) {
                        continue;
                    }
                    final Deque<PooledObject<T>> idleObjects = objectDeque.getIdleObjects();
                    evictionIterator = new EvictionIterator(idleObjects);
                    if (evictionIterator.hasNext()) {
                        break;
                    }
                    evictionIterator = null;
                }
            }
            if (evictionIterator == null) {
                // Pools exhausted
                return;
            }
            final Deque<PooledObject<T>> idleObjects;
            try {
                underTest = evictionIterator.next();
                idleObjects = evictionIterator.getIdleObjects();
            } catch (final NoSuchElementException nsee) {
                // Object was borrowed in another thread
                // Don't count this as an eviction test so reduce i;
                i--;
                evictionIterator = null;
                continue;
            }
            if (!underTest.startEvictionTest()) {
                // Object was borrowed in another thread
                // Don't count this as an eviction test so reduce i;
                i--;
                continue;
            }
            // User provided eviction policy could throw all sorts of
            // crazy exceptions. Protect against such an exception
            // killing the eviction thread.
            boolean evict;
            try {
                evict = evictionPolicy.evict(evictionConfig, underTest, poolMap.get(evictionKey).getIdleObjects().size());
            } catch (final Throwable t) {
                // Slightly convoluted as SwallowedExceptionListener
                // uses Exception rather than Throwable
                PoolUtils.checkRethrow(t);
                swallowException(new Exception(t));
                // Don't evict on error conditions
                evict = false;
            }
            if (evict) {
                destroy(evictionKey, underTest, true);
                destroyedByEvictorCount.incrementAndGet();
            } else {
                if (testWhileIdle) {
                    boolean active = false;
                    try {
                        factory.activateObject(evictionKey, underTest);
                        active = true;
                    } catch (final Exception e) {
                        destroy(evictionKey, underTest, true);
                        destroyedByEvictorCount.incrementAndGet();
                    }
                    if (active) {
                        if (!factory.validateObject(evictionKey, underTest)) {
                            destroy(evictionKey, underTest, true);
                            destroyedByEvictorCount.incrementAndGet();
                        } else {
                            try {
                                factory.passivateObject(evictionKey, underTest);
                            } catch (final Exception e) {
                                destroy(evictionKey, underTest, true);
                                destroyedByEvictorCount.incrementAndGet();
                            }
                        }
                    }
                }
                if (!underTest.endEvictionTest(idleObjects)) {
                // TODO - May need to add code here once additional
                // states are used
                }
            }
        }
    }
}
Also used : ArrayList(java.util.ArrayList) NoSuchElementException(java.util.NoSuchElementException) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) Lock(java.util.concurrent.locks.Lock) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) PooledObject(org.datanucleus.store.rdbms.datasource.dbcp2.pool2.PooledObject) NoSuchElementException(java.util.NoSuchElementException)

Example 7 with PooledObject

use of org.datanucleus.store.rdbms.datasource.dbcp2.pool2.PooledObject in project datanucleus-rdbms by datanucleus.

the class PoolableConnectionFactory method makeObject.

@Override
public PooledObject<PoolableConnection> makeObject() throws Exception {
    Connection conn = connectionFactory.createConnection();
    if (conn == null) {
        throw new IllegalStateException("Connection factory returned null from createConnection");
    }
    try {
        initializeConnection(conn);
    } catch (final SQLException sqle) {
        // Make sure the connection is closed
        try {
            conn.close();
        } catch (final SQLException ignore) {
        // ignore
        }
        // Rethrow original exception so it is visible to caller
        throw sqle;
    }
    final long connIndex = connectionIndex.getAndIncrement();
    if (poolStatements) {
        conn = new PoolingConnection(conn);
        final GenericKeyedObjectPoolConfig<DelegatingPreparedStatement> config = new GenericKeyedObjectPoolConfig<>();
        config.setMaxTotalPerKey(-1);
        config.setBlockWhenExhausted(false);
        config.setMaxWaitMillis(0);
        config.setMaxIdlePerKey(1);
        config.setMaxTotal(maxOpenPreparedStatements);
        if (dataSourceJmxObjectName != null) {
            final StringBuilder base = new StringBuilder(dataSourceJmxObjectName.toString());
            base.append(Constants.JMX_CONNECTION_BASE_EXT);
            base.append(Long.toString(connIndex));
            config.setJmxNameBase(base.toString());
            config.setJmxNamePrefix(Constants.JMX_STATEMENT_POOL_PREFIX);
        } else {
            config.setJmxEnabled(false);
        }
        final PoolingConnection poolingConn = (PoolingConnection) conn;
        final KeyedObjectPool<PStmtKey, DelegatingPreparedStatement> stmtPool = new GenericKeyedObjectPool<>(poolingConn, config);
        poolingConn.setStatementPool(stmtPool);
        poolingConn.setCacheState(cacheState);
    }
    // Register this connection with JMX
    ObjectName connJmxName;
    if (dataSourceJmxObjectName == null) {
        connJmxName = null;
    } else {
        connJmxName = new ObjectName(dataSourceJmxObjectName.toString() + Constants.JMX_CONNECTION_BASE_EXT + connIndex);
    }
    final PoolableConnection pc = new PoolableConnection(conn, pool, connJmxName, disconnectionSqlCodes, fastFailValidation);
    pc.setCacheState(cacheState);
    return new DefaultPooledObject<>(pc);
}
Also used : GenericKeyedObjectPoolConfig(org.datanucleus.store.rdbms.datasource.dbcp2.pool2.impl.GenericKeyedObjectPoolConfig) SQLException(java.sql.SQLException) GenericKeyedObjectPool(org.datanucleus.store.rdbms.datasource.dbcp2.pool2.impl.GenericKeyedObjectPool) Connection(java.sql.Connection) ObjectName(javax.management.ObjectName) DefaultPooledObject(org.datanucleus.store.rdbms.datasource.dbcp2.pool2.impl.DefaultPooledObject)

Example 8 with PooledObject

use of org.datanucleus.store.rdbms.datasource.dbcp2.pool2.PooledObject in project new-cloud by xie-summer.

the class JedisPoolTest method returnResourceDestroysResourceOnException.

@Test
public void returnResourceDestroysResourceOnException() {
    class CrashingJedis extends Jedis {

        @Override
        public void resetState() {
            throw new RuntimeException();
        }
    }
    final AtomicInteger destroyed = new AtomicInteger(0);
    class CrashingJedisPooledObjectFactory implements PooledObjectFactory<Jedis> {

        @Override
        public PooledObject<Jedis> makeObject() throws Exception {
            return new DefaultPooledObject<Jedis>(new CrashingJedis());
        }

        @Override
        public void destroyObject(PooledObject<Jedis> p) throws Exception {
            destroyed.incrementAndGet();
        }

        @Override
        public boolean validateObject(PooledObject<Jedis> p) {
            return true;
        }

        @Override
        public void activateObject(PooledObject<Jedis> p) throws Exception {
        }

        @Override
        public void passivateObject(PooledObject<Jedis> p) throws Exception {
        }
    }
    GenericObjectPoolConfig config = new GenericObjectPoolConfig();
    config.setMaxTotal(1);
    JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort(), 2000, "foobared");
    pool.initPool(config, new CrashingJedisPooledObjectFactory());
    Jedis crashingJedis = pool.getResource();
    try {
        crashingJedis.close();
    } catch (Exception ignored) {
    }
    assertEquals(destroyed.get(), 1);
}
Also used : Jedis(redis.clients.jedis.Jedis) DefaultPooledObject(org.apache.commons.pool2.impl.DefaultPooledObject) PooledObjectFactory(org.apache.commons.pool2.PooledObjectFactory) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PooledObject(org.apache.commons.pool2.PooledObject) DefaultPooledObject(org.apache.commons.pool2.impl.DefaultPooledObject) GenericObjectPoolConfig(org.apache.commons.pool2.impl.GenericObjectPoolConfig) JedisPool(redis.clients.jedis.JedisPool) URISyntaxException(java.net.URISyntaxException) JedisException(redis.clients.jedis.exceptions.JedisException) InvalidURIException(redis.clients.jedis.exceptions.InvalidURIException) JedisConnectionException(redis.clients.jedis.exceptions.JedisConnectionException) Test(org.junit.Test)

Example 9 with PooledObject

use of org.datanucleus.store.rdbms.datasource.dbcp2.pool2.PooledObject in project datanucleus-rdbms by datanucleus.

the class GenericObjectPool method returnObject.

/**
 * {@inheritDoc}
 * <p>
 * If {@link #getMaxIdle() maxIdle} is set to a positive value and the
 * number of idle instances has reached this value, the returning instance
 * is destroyed.
 * <p>
 * If {@link #getTestOnReturn() testOnReturn} == true, the returning
 * instance is validated before being returned to the idle instance pool. In
 * this case, if validation fails, the instance is destroyed.
 * <p>
 * Exceptions encountered destroying objects for any reason are swallowed
 * but notified via a {@link SwallowedExceptionListener}.
 */
@Override
public void returnObject(T obj) {
    PooledObject<T> p = allObjects.get(new IdentityWrapper<T>(obj));
    if (p == null) {
        if (!isAbandonedConfig()) {
            throw new IllegalStateException("Returned object not currently part of this pool");
        }
        // Object was abandoned and removed
        return;
    }
    synchronized (p) {
        final PooledObjectState state = p.getState();
        if (state != PooledObjectState.ALLOCATED) {
            throw new IllegalStateException("Object has already been returned to this pool or is invalid");
        }
        // Keep from being marked abandoned
        p.markReturning();
    }
    long activeTime = p.getActiveTimeMillis();
    if (getTestOnReturn()) {
        if (!factory.validateObject(p)) {
            try {
                destroy(p);
            } catch (Exception e) {
                swallowException(e);
            }
            try {
                ensureIdle(1, false);
            } catch (Exception e) {
                swallowException(e);
            }
            updateStatsReturn(activeTime);
            return;
        }
    }
    try {
        factory.passivateObject(p);
    } catch (Exception e1) {
        swallowException(e1);
        try {
            destroy(p);
        } catch (Exception e) {
            swallowException(e);
        }
        try {
            ensureIdle(1, false);
        } catch (Exception e) {
            swallowException(e);
        }
        updateStatsReturn(activeTime);
        return;
    }
    if (!p.deallocate()) {
        throw new IllegalStateException("Object has already been returned to this pool or is invalid");
    }
    int maxIdleSave = getMaxIdle();
    if (isClosed() || maxIdleSave > -1 && maxIdleSave <= idleObjects.size()) {
        try {
            destroy(p);
        } catch (Exception e) {
            swallowException(e);
        }
    } else {
        if (getLifo()) {
            idleObjects.addFirst(p);
        } else {
            idleObjects.addLast(p);
        }
        if (isClosed()) {
            // Pool closed while object was being added to idle objects.
            // Make sure the returned object is destroyed rather than left
            // in the idle object pool (which would effectively be a leak)
            clear();
        }
    }
    updateStatsReturn(activeTime);
}
Also used : PooledObjectState(org.datanucleus.store.rdbms.datasource.dbcp2.pool2.PooledObjectState) NoSuchElementException(java.util.NoSuchElementException)

Example 10 with PooledObject

use of org.datanucleus.store.rdbms.datasource.dbcp2.pool2.PooledObject in project datanucleus-rdbms by datanucleus.

the class PooledConnectionImpl method passivateObject.

/**
 * My {@link KeyedPooledObjectFactory} method for passivating {@link PreparedStatement}s. Currently invokes
 * {@link PreparedStatement#clearParameters}.
 *
 * @param key
 *            ignored
 * @param pooledObject
 *            a wrapped {@link PreparedStatement}
 */
@Override
public void passivateObject(final PStmtKey key, final PooledObject<DelegatingPreparedStatement> pooledObject) throws Exception {
    @SuppressWarnings("resource") final DelegatingPreparedStatement dps = pooledObject.getObject();
    dps.clearParameters();
    dps.passivate();
}
Also used : DelegatingPreparedStatement(org.datanucleus.store.rdbms.datasource.dbcp2.DelegatingPreparedStatement)

Aggregations

NoSuchElementException (java.util.NoSuchElementException)5 PooledObject (org.apache.commons.pool2.PooledObject)5 DefaultPooledObject (org.apache.commons.pool2.impl.DefaultPooledObject)5 DefaultPooledObject (org.datanucleus.store.rdbms.datasource.dbcp2.pool2.impl.DefaultPooledObject)5 URISyntaxException (java.net.URISyntaxException)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 PooledObjectFactory (org.apache.commons.pool2.PooledObjectFactory)4 GenericObjectPoolConfig (org.apache.commons.pool2.impl.GenericObjectPoolConfig)4 Test (org.junit.Test)4 InvalidURIException (redis.clients.jedis.exceptions.InvalidURIException)4 JedisException (redis.clients.jedis.exceptions.JedisException)4 ArrayList (java.util.ArrayList)3 PooledConnection (javax.sql.PooledConnection)3 PooledObject (org.apache.tomcat.dbcp.pool2.PooledObject)3 PooledObjectState (org.datanucleus.store.rdbms.datasource.dbcp2.pool2.PooledObjectState)3 Jedis (redis.clients.jedis.Jedis)3 JedisPool (redis.clients.jedis.JedisPool)3 JedisConnectionException (redis.clients.jedis.exceptions.JedisConnectionException)3 CallableStatement (java.sql.CallableStatement)2 Connection (java.sql.Connection)2