You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Kris Nuttycombe <Kr...@noaa.gov> on 2003/02/25 01:22:35 UTC

PATCH: Idle object eviction config for BasicDataSource

Since Tomcat's JNDI implementation examples use the 
org.apache.com.dbcp.BasicDataSource, I suspect that a bunch of people 
have encountered the following problem, as I have: BasicDataSource is 
not set up to allow overriding of the underlying GenericObjectPool's 
defaults for time between eviction runs and TTL for idle connections. 
This has been causing me problems in cases where the database server 
kills what it presumes to be abandoned connections. In my particular 
application, it is not possible to use validation queries, mostly 
because of maintainance concerns, so idle object eviction is the only 
real solution, but it is disabled by default.

The following patches for BasicDataSource and BasicDataSourceFactory 
provide the necessary methods to make idle object eviction in the 
underlying pool configurable while maintaining the same defaults as the 
GenericObjectPool.

Kris Nuttycombe



Index: BasicDataSource.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/BasicDataSource.java,v
retrieving revision 1.11
diff -u -r1.11 BasicDataSource.java
--- BasicDataSource.java        21 Jul 2002 00:38:35 -0000      1.11
+++ BasicDataSource.java        24 Feb 2003 23:59:32 -0000
@@ -119,6 +119,21 @@


     /**
+     * The action to take when a new connection is requested from the pool
+     * and the maximum number of active connections has been met.
+     */
+    protected byte whenExhaustedAction = 
GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
+
+    public byte getWhenExhaustedAction() {
+        return (this.whenExhaustedAction);
+    }
+
+    public void setWhenExhaustedAction(byte whenExhaustedAction) {
+        this.whenExhaustedAction = whenExhaustedAction;
+    }
+
+
+    /**
      * The fully qualified Java class name of the JDBC driver to be used.
      */
     protected String driverClassName = null;
@@ -180,6 +195,55 @@


     /**
+     * The number of milliseconds to sleep between runs of the
+     * underlying pool's idle object evictor thread.
+     * When non-positive, no idle object evictor thread will be run.
+     */
+    protected long timeBetweenEvictionRunsMillis = 
GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
+
+    public long getTimeBetweenEvictionRunsMillis() {
+        return (this.timeBetweenEvictionRunsMillis);
+    }
+
+    public void setTimeBetweenEvictionRunsMillis(long 
timeBetweenEvictionRunsMillis) {
+        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
+    }
+
+
+
+    /**
+     * The minimum number of milliseconds that a connection is permitted
+     * to sit idle in the underlying pool before it may be removed by the
+     * idle object eviction thread.
+     */
+    protected long minEvictableIdleTimeMillis = 
GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
+
+    public long getMinEvictableIdleTimeMillis() {
+        return (this.minEvictableIdleTimeMillis);
+    }
+
+    public void setMinEvictableIdleTimeMillis(long 
minEvictableIdleTimeMillis) {
+        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
+    }
+
+
+
+    /**
+     * The number of objects to examine per run of the idle object evictor.
+     */
+    protected int numTestsPerEvictionRun = 
GenericObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
+
+    public int getNumTestsPerEvictionRun() {
+        return (this.numTestsPerEvictionRun);
+    }
+
+    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
+        this.numTestsPerEvictionRun = numTestsPerEvictionRun;
+    }
+
+
+
+    /**
      * [Read Only] The current number of active connections that have been
      * allocated from this data source.
      */
@@ -543,9 +607,13 @@

         // Create an object pool to contain our active connections
         connectionPool = new AbandonedObjectPool(null,abandonedConfig);
+        connectionPool.setWhenExhaustedAction(whenExhaustedAction);
         connectionPool.setMaxActive(maxActive);
         connectionPool.setMaxIdle(maxIdle);
         connectionPool.setMaxWait(maxWait);
+        
connectionPool.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+        
connectionPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
+        connectionPool.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
         if (validationQuery != null) {
             connectionPool.setTestOnBorrow(true);
         }




Index: BasicDataSourceFactory.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/BasicDataSourceFactory.java,v
retrieving revision 1.3
diff -u -r1.3 BasicDataSourceFactory.java
--- BasicDataSourceFactory.java 21 Jun 2002 21:56:13 -0000      1.3
+++ BasicDataSourceFactory.java 25 Feb 2003 00:00:23 -0000
@@ -68,6 +68,7 @@
 import javax.naming.Reference;
 import javax.naming.RefAddr;
 import javax.naming.spi.ObjectFactory;
+import org.apache.commons.pool.impl.GenericObjectPool;


 /**
@@ -192,6 +193,38 @@
         if (ra != null) {
             dataSource.setLogAbandoned
                 
(Boolean.valueOf(ra.getContent().toString()).booleanValue());
+        }
+
+        ra = ref.get("timeBetweenEvictionRunsMillis");
+        if (ra != null) {
+            dataSource.setTimeBetweenEvictionRunsMillis
+                (Long.parseLong(ra.getContent().toString()));
+        }
+
+        ra = ref.get("minEvictableIdleTimeMillis");
+        if (ra != null) {
+            dataSource.setMinEvictableIdleTimeMillis
+                (Long.parseLong(ra.getContent().toString()));
+        }
+
+        ra = ref.get("numTestsPerEvictionRun");
+        if (ra != null) {
+            dataSource.setNumTestsPerEvictionRun
+                (Integer.parseInt(ra.getContent().toString()));
+        }
+
+        ra = ref.get("whenExhaustedAction");
+        if (ra != null) {
+            String action = ra.getContent().toString();
+            if ("block".equals(action)) {
+                
dataSource.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
+            } else if ("fail".equals(action)) {
+                
dataSource.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_FAIL);
+            } else if ("grow".equals(action)) {
+                
dataSource.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_GROW);
+            } else {
+                
dataSource.setWhenExhaustedAction(GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION);
+            }
         }

         // Return the configured data source instance

-- 
=====================================================
Kris Nuttycombe
Associate Scientist
Geospatial Data Services Group
CIRES, National Geophysical Data Center/NOAA
(303) 497-6337
Kris.Nuttycombe@noaa.gov
=====================================================






---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org