Author: fhanik Date: Fri May 18 16:28:33 2012 New Revision: 1340160 URL: http://svn.apache.org/viewvc?rev=1340160&view=rev Log: Add in ability to purge the pool https://issues.apache.org/bugzilla/show_bug.cgi?id=53254
Added: tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/PoolPurgeTest.java (with props) Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java?rev=1340160&r1=1340159&r2=1340160&view=diff ============================================================================== --- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java (original) +++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java Fri May 18 16:28:33 2012 @@ -39,6 +39,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; @@ -120,6 +121,8 @@ public class ConnectionPool { */ private AtomicInteger waitcount = new AtomicInteger(0); + private AtomicLong poolVersion = new AtomicLong(Long.MIN_VALUE); + //=============================================================================== // PUBLIC METHODS //=============================================================================== @@ -438,6 +441,8 @@ public class ConnectionPool { if (properties.isFairQueue()) { idle = new FairBlockingQueue<PooledConnection>(); //idle = new MultiLockFairBlockingQueue<PooledConnection>(); + //idle = new LinkedTransferQueue<PooledConnection>(); + //idle = new ArrayBlockingQueue<PooledConnection>(properties.getMaxActive(),false); } else { idle = new ArrayBlockingQueue<PooledConnection>(properties.getMaxActive(),properties.isFairQueue()); } @@ -836,6 +841,7 @@ public class ConnectionPool { * @return true if the connection should be closed */ protected boolean shouldClose(PooledConnection con, int action) { + if (con.getConnectionVersion() < getPoolVersion()) return true; if (con.isDiscarded()) return true; if (isClosed()) return true; if (!con.validate(action)) return true; @@ -954,11 +960,16 @@ public class ConnectionPool { * {@link PoolProperties#maxIdle}, {@link PoolProperties#minIdle}, {@link PoolProperties#minEvictableIdleTimeMillis} */ public void checkIdle() { + checkIdle(false); + } + + public void checkIdle(boolean ignoreMinSize) { + try { if (idle.size()==0) return; long now = System.currentTimeMillis(); Iterator<PooledConnection> unlocked = idle.iterator(); - while ( (idle.size()>=getPoolProperties().getMinIdle()) && unlocked.hasNext()) { + while ( (ignoreMinSize || (idle.size()>=getPoolProperties().getMinIdle())) && unlocked.hasNext()) { PooledConnection con = unlocked.next(); boolean setToNull = false; try { @@ -967,7 +978,7 @@ public class ConnectionPool { if (busy.contains(con)) continue; long time = con.getTimestamp(); - if ((con.getReleaseTime()>0) && ((now - time) > con.getReleaseTime()) && (getSize()>getPoolProperties().getMinIdle())) { + if (shouldReleaseIdle(now, con, time)) { release(con); idle.remove(con); setToNull = true; @@ -988,6 +999,12 @@ public class ConnectionPool { } + + protected boolean shouldReleaseIdle(long now, PooledConnection con, long time) { + if (con.getConnectionVersion() < getPoolVersion()) return true; + else return (con.getReleaseTime()>0) && ((now - time) > con.getReleaseTime()) && (getSize()>getPoolProperties().getMinIdle()); + } + /** * Forces a validation of all idle connections if {@link PoolProperties#testWhileIdle} is set. */ @@ -1058,6 +1075,27 @@ public class ConnectionPool { } /** + * Purges all connections in the pool. + * For connections currently in use, these connections will be + * purged when returned on the pool. This call also + * purges connections that are idle and in the pool + * To only purge used/active connections see {@link #purgeOnReturn()} + */ + public void purge() { + purgeOnReturn(); + checkIdle(true); + } + + /** + * Purges connections when they are returned from the pool. + * This call does not purge idle connections until they are used. + * To purge idle connections see {@link #purge()} + */ + public void purgeOnReturn() { + poolVersion.incrementAndGet(); + } + + /** * Hook to perform final actions on a pooled connection object once it has been disconnected and will be discarded * @param con */ @@ -1252,6 +1290,10 @@ public class ConnectionPool { return Collections.<TimerTask>unmodifiableSet(cleaners); } + public long getPoolVersion() { + return poolVersion.get(); + } + public static Timer getPoolTimer() { return poolCleanTimer; } Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java?rev=1340160&r1=1340159&r2=1340160&view=diff ============================================================================== --- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java (original) +++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java Fri May 18 16:28:33 2012 @@ -1288,4 +1288,26 @@ public class DataSourceProxy implements getPoolProperties().setPropagateInterruptState(propagateInterruptState); } + /** + * {@inheritDoc} + */ + public void purge() { + try { + createPool().purge(); + }catch (SQLException x) { + log.error("Unable to purge pool.",x); + } + } + + /** + * {@inheritDoc} + */ + public void purgeOnReturn() { + try { + createPool().purgeOnReturn(); + }catch (SQLException x) { + log.error("Unable to purge pool.",x); + } + } + } Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java?rev=1340160&r1=1340159&r2=1340160&view=diff ============================================================================== --- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java (original) +++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java Fri May 18 16:28:33 2012 @@ -104,6 +104,8 @@ public class PooledConnection { private HashMap<Object, Object> attributes = new HashMap<Object, Object>(); + private volatile long connectionVersion=0; + /** * Weak reference to cache the list of interceptors for this connection * so that we don't create a new list of interceptors each time we borrow @@ -125,6 +127,11 @@ public class PooledConnection { public PooledConnection(PoolConfiguration prop, ConnectionPool parent) { poolProperties = prop; this.parent = parent; + connectionVersion = parent.getPoolVersion(); + } + + public long getConnectionVersion() { + return connectionVersion; } public boolean checkUser(String username, String password) { Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java?rev=1340160&r1=1340159&r2=1340160&view=diff ============================================================================== --- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java (original) +++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java Fri May 18 16:28:33 2012 @@ -828,6 +828,26 @@ public class ConnectionPool extends Noti getPoolProperties().setPropagateInterruptState(propagateInterruptState); } + /** + * {@inheritDoc} + */ + @Override + public void purge() { + pool.purge(); + + } + + /** + * {@inheritDoc} + */ + @Override + public void purgeOnReturn() { + pool.purgeOnReturn(); + + } + + + } Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java?rev=1340160&r1=1340159&r2=1340160&view=diff ============================================================================== --- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java (original) +++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java Fri May 18 16:28:33 2012 @@ -44,6 +44,22 @@ public interface ConnectionPoolMBean ext public void testIdle(); + /** + * Purges all connections in the pool. + * For connections currently in use, these connections will be + * purged when returned on the pool. This call also + * purges connections that are idle and in the pool + * To only purge used/active connections see {@link #purgeOnReturn()} + */ + public void purge(); + + /** + * Purges connections when they are returned from the pool. + * This call does not purge idle connections until they are used. + * To purge idle connections see {@link #purge()} + */ + public void purgeOnReturn(); + //================================================================= // POOL NOTIFICATIONS //================================================================= Added: tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/PoolPurgeTest.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/PoolPurgeTest.java?rev=1340160&view=auto ============================================================================== --- tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/PoolPurgeTest.java (added) +++ tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/PoolPurgeTest.java Fri May 18 16:28:33 2012 @@ -0,0 +1,99 @@ +/* + * 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. + */ +package org.apache.tomcat.jdbc.test; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import javax.sql.DataSource; + +import org.apache.tomcat.jdbc.pool.DataSourceProxy; +import org.apache.tomcat.jdbc.test.driver.Driver; + +/** + * @author Filip Hanik + * @version 1.0 + */ +public class PoolPurgeTest extends DefaultTestCase { + public PoolPurgeTest(String name) { + super(name); + } + + static final int expectedSize = 2; + + + @Override + public org.apache.tomcat.jdbc.pool.DataSource createDefaultDataSource() { + // TODO Auto-generated method stub + org.apache.tomcat.jdbc.pool.DataSource ds = super.createDefaultDataSource(); + ds.getPoolProperties().setDriverClassName(Driver.class.getName()); + ds.getPoolProperties().setUrl(Driver.url); + ds.getPoolProperties().setInitialSize(expectedSize); + ds.getPoolProperties().setMaxIdle(expectedSize); + ds.getPoolProperties().setMinIdle(expectedSize); + ds.getPoolProperties().setMaxActive(expectedSize); + ds.getPoolProperties().setTimeBetweenEvictionRunsMillis(30000); + ds.getPoolProperties().setMaxAge(Long.MAX_VALUE); + return ds; + } + + + @Override + protected void tearDown() throws Exception { + Driver.reset(); + super.tearDown(); + } + + + + public void testPoolPurge() throws Exception { + init(); + this.datasource.getConnection().close(); + assertEquals("Nr of connections should be "+expectedSize, expectedSize , datasource.getSize()); + this.datasource.purge(); + assertEquals("Nr of connections should be 0", 0 , datasource.getSize()); + tearDown(); + } + + public void testPoolPurgeWithActive() throws Exception { + init(); + java.sql.Connection con = datasource.getConnection(); + assertEquals("Nr of connections should be "+expectedSize, expectedSize , datasource.getSize()); + this.datasource.purge(); + assertEquals("Nr of connections should be "+(expectedSize-1), (expectedSize-1) , datasource.getSize()); + con.close(); + assertEquals("Nr of connections should be 0", 0 , datasource.getSize()); + tearDown(); + } + + public void testPoolPurgeOnReturn() throws Exception { + init(); + java.sql.Connection con = datasource.getConnection(); + assertEquals("Nr of connections should be "+expectedSize, expectedSize , datasource.getSize()); + this.datasource.purgeOnReturn(); + assertEquals("Nr of connections should be "+expectedSize, expectedSize , datasource.getSize()); + con.close(); + assertEquals("Nr of connections should be "+(expectedSize-1), (expectedSize-1) , datasource.getSize()); + tearDown(); + } + +} + Propchange: tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/PoolPurgeTest.java ------------------------------------------------------------------------------ svn:eol-style = native --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org