You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by fh...@apache.org on 2012/05/18 18:28:33 UTC

svn commit: r1340160 - in /tomcat/trunk/modules/jdbc-pool/src: main/java/org/apache/tomcat/jdbc/pool/ main/java/org/apache/tomcat/jdbc/pool/jmx/ test/java/org/apache/tomcat/jdbc/test/

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org