You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ma...@apache.org on 2012/02/09 23:38:07 UTC

svn commit: r1242578 - in /commons/proper/pool/trunk/src: changes/ java/org/apache/commons/pool2/impl/ test/org/apache/commons/pool2/impl/

Author: markt
Date: Thu Feb  9 22:38:07 2012
New Revision: 1242578

URL: http://svn.apache.org/viewvc?rev=1242578&view=rev
Log:
Fix POOL-100.
Make eviction policy configurable. Includes a simple test case.

Modified:
    commons/proper/pool/trunk/src/changes/changes.xml
    commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/BaseObjectPoolConfig.java
    commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/DefaultEvictionPolicy.java
    commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java
    commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericObjectPool.java
    commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericObjectPool.java

Modified: commons/proper/pool/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/changes/changes.xml?rev=1242578&r1=1242577&r2=1242578&view=diff
==============================================================================
--- commons/proper/pool/trunk/src/changes/changes.xml (original)
+++ commons/proper/pool/trunk/src/changes/changes.xml Thu Feb  9 22:38:07 2012
@@ -92,6 +92,9 @@ clarify behaviour and improve consistenc
       Change meaning of zero for maxWait to a maximum wait of zero milliseconds
       rather than the unexpected infinite wait.
     </action>
+    <action dev="markt" type="fix" issue="POOL-100">
+      Allow custom eviction policies to be defined.
+    </action>
   </release>
   <release version="1.5.6" date="2011-04-03" description="This is a patch release, including bugfixes only.">
     <action dev="markt" type="fix" issue="POOL-179" due-to="Axel Grossmann">

Modified: commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/BaseObjectPoolConfig.java
URL: http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/BaseObjectPoolConfig.java?rev=1242578&r1=1242577&r2=1242578&view=diff
==============================================================================
--- commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/BaseObjectPoolConfig.java (original)
+++ commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/BaseObjectPoolConfig.java Thu Feb  9 22:38:07 2012
@@ -92,6 +92,12 @@ public abstract class BaseObjectPoolConf
      */
     public static final String DEFAULT_JMX_NAME_PREFIX = "pool";
 
+    /**
+     * The default policy that will be used to evict objects from the pool.
+     */
+    public static final String DEFAULT_EVICTION_POLICY_CLASS_NAME =
+            DefaultEvictionPolicy.class.getName();
+
     private boolean lifo = DEFAULT_LIFO;
 
     private long maxWait = DEFAULT_MAX_WAIT;
@@ -105,6 +111,8 @@ public abstract class BaseObjectPoolConf
     private int numTestsPerEvictionRun =
         DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
 
+    private String evictionPolicyClassName = DEFAULT_EVICTION_POLICY_CLASS_NAME;
+    
     private boolean testOnBorrow = DEFAULT_TEST_ON_BORROW;
 
     private boolean testOnReturn = DEFAULT_TEST_ON_RETURN;
@@ -193,6 +201,14 @@ public abstract class BaseObjectPoolConf
         this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
     }
 
+    public String getEvictionPolicyClassName() {
+        return evictionPolicyClassName;
+    }
+
+    public void setEvictionPolicyClassName(String evictionPolicyClassName) {
+        this.evictionPolicyClassName = evictionPolicyClassName;
+    }
+
     public boolean getBlockWhenExhausted() {
         return blockWhenExhausted;
     }

Modified: commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/DefaultEvictionPolicy.java
URL: http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/DefaultEvictionPolicy.java?rev=1242578&r1=1242577&r2=1242578&view=diff
==============================================================================
--- commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/DefaultEvictionPolicy.java (original)
+++ commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/DefaultEvictionPolicy.java Thu Feb  9 22:38:07 2012
@@ -16,6 +16,17 @@
  */
 package org.apache.commons.pool2.impl;
 
+/**
+ * Objects will be evicted if the following conditions are met:
+ * <ul>
+ * <li>the object has been idle longer than
+ *     {@link BaseObjectPoolConfig#getMinEvictableIdleTimeMillis()}</li>
+ * <li>there are more than {@link GenericObjectPool#getMinIdle()} /
+ *     (@link GenericKeyedObjectPoolConfig#getMinIdlePerKey()} idle objects in
+ *     the pool and the object has been idle for longer tham
+ *     {@link BaseObjectPoolConfig#getSoftMinEvictableIdleTimeMillis()}
+ * </ul>
+ */
 public class DefaultEvictionPolicy<T> implements EvictionPolicy<T> {
 
     public boolean evict(EvictionConfig config, PooledObject<T> underTest,

Modified: commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java
URL: http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java?rev=1242578&r1=1242577&r2=1242578&view=diff
==============================================================================
--- commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java (original)
+++ commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java Thu Feb  9 22:38:07 2012
@@ -238,9 +238,6 @@ public class GenericKeyedObjectPool<K,T>
         this.factory = factory;
         setConfig(config);
 
-        // TODO Get from config
-        this.evictionPolicy = new DefaultEvictionPolicy<T>();
-        
         startEvictor(getMinEvictableIdleTimeMillis());
 
         initStats();
@@ -632,6 +629,33 @@ public class GenericKeyedObjectPool<K,T>
         this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
     }
 
+    public String getEvictionPolicyClassName() {
+        return evictionPolicy.getClass().getName();
+    }
+
+    @SuppressWarnings("unchecked")
+    public void setEvictionPolicyClassName(String evictionPolicyClassName) {
+        try {
+            Class<?> clazz = Class.forName(evictionPolicyClassName);
+            Object policy = clazz.newInstance();
+            if (policy instanceof EvictionPolicy<?>) {
+                this.evictionPolicy = (EvictionPolicy<T>) policy;
+            }
+        } catch (ClassNotFoundException e) {
+            throw new IllegalArgumentException(
+                    "Unable to create EvictionPolicy instance of type " +
+                    evictionPolicyClassName, e);
+        } catch (InstantiationException e) {
+            throw new IllegalArgumentException(
+                    "Unable to create EvictionPolicy instance of type " +
+                    evictionPolicyClassName, e);
+        } catch (IllegalAccessException e) {
+            throw new IllegalArgumentException(
+                    "Unable to create EvictionPolicy instance of type " +
+                    evictionPolicyClassName, e);
+        }
+    }
+    
     /**
      * When <code>true</code>, objects will be
      * {@link org.apache.commons.pool2.PoolableObjectFactory#validateObject validated}
@@ -682,6 +706,7 @@ public class GenericKeyedObjectPool<K,T>
                 conf.getSoftMinEvictableIdleTimeMillis());
         setTimeBetweenEvictionRunsMillis(
                 conf.getTimeBetweenEvictionRunsMillis());
+        setEvictionPolicyClassName(conf.getEvictionPolicyClassName());
     }
 
     /**

Modified: commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericObjectPool.java
URL: http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericObjectPool.java?rev=1242578&r1=1242577&r2=1242578&view=diff
==============================================================================
--- commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericObjectPool.java (original)
+++ commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericObjectPool.java Thu Feb  9 22:38:07 2012
@@ -191,9 +191,6 @@ public class GenericObjectPool<T> extend
         this.factory = factory;
         setConfig(config);
 
-        // TODO Get from config
-        this.evictionPolicy = new DefaultEvictionPolicy<T>();
-        
         startEvictor(getTimeBetweenEvictionRunsMillis());
 
         initStats();
@@ -566,6 +563,33 @@ public class GenericObjectPool<T> extend
         this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
     }
 
+    public String getEvictionPolicyClassName() {
+        return evictionPolicy.getClass().getName();
+    }
+
+    @SuppressWarnings("unchecked")
+    public void setEvictionPolicyClassName(String evictionPolicyClassName) {
+        try {
+            Class<?> clazz = Class.forName(evictionPolicyClassName);
+            Object policy = clazz.newInstance();
+            if (policy instanceof EvictionPolicy<?>) {
+                this.evictionPolicy = (EvictionPolicy<T>) policy;
+            }
+        } catch (ClassNotFoundException e) {
+            throw new IllegalArgumentException(
+                    "Unable to create EvictionPolicy instance of type " +
+                    evictionPolicyClassName, e);
+        } catch (InstantiationException e) {
+            throw new IllegalArgumentException(
+                    "Unable to create EvictionPolicy instance of type " +
+                    evictionPolicyClassName, e);
+        } catch (IllegalAccessException e) {
+            throw new IllegalArgumentException(
+                    "Unable to create EvictionPolicy instance of type " +
+                    evictionPolicyClassName, e);
+        }
+    }
+
     /**
      * When <tt>true</tt>, objects will be
      * {@link PoolableObjectFactory#validateObject validated} by the idle object
@@ -647,6 +671,7 @@ public class GenericObjectPool<T> extend
                 conf.getTimeBetweenEvictionRunsMillis());
         setSoftMinEvictableIdleTimeMillis(
                 conf.getSoftMinEvictableIdleTimeMillis());
+        setEvictionPolicyClassName(conf.getEvictionPolicyClassName());
     }
 
     /**
@@ -1574,7 +1599,7 @@ public class GenericObjectPool<T> extend
     /**
      * Policy that determines if an object is eligible for eviction or not.
      */
-    private EvictionPolicy<T> evictionPolicy;
+    private EvictionPolicy<T> evictionPolicy = new DefaultEvictionPolicy<T>();
 
     /** Object used to ensure thread safety of eviction process */ 
     private final Object evictionLock = new Object();

Modified: commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericObjectPool.java
URL: http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericObjectPool.java?rev=1242578&r1=1242577&r2=1242578&view=diff
==============================================================================
--- commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericObjectPool.java (original)
+++ commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericObjectPool.java Thu Feb  9 22:38:07 2012
@@ -25,6 +25,7 @@ import static junit.framework.Assert.fai
 
 import java.util.NoSuchElementException;
 import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.commons.pool2.BasePoolableObjectFactory;
 import org.apache.commons.pool2.ObjectPool;
@@ -853,6 +854,45 @@ public class TestGenericObjectPool exten
         assertEquals("Should be zero idle, found " + pool.getNumIdle(),0,pool.getNumIdle());
     }
  
+    public static class TestEvictionPolicy<T> implements EvictionPolicy<T> {
+
+        private AtomicInteger callCount = new AtomicInteger(0);
+        
+        public boolean evict(EvictionConfig config, PooledObject<T> underTest,
+                int idleCount) {
+            if (callCount.incrementAndGet() > 1500) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+    
+    @Test(timeout=60000)
+    public void testEvictionPolicy() throws Exception {
+        pool.setMaxIdle(500);
+        pool.setMaxTotal(500);
+        pool.setNumTestsPerEvictionRun(500);
+        pool.setMinEvictableIdleTimeMillis(250L);
+        pool.setTimeBetweenEvictionRunsMillis(500L);
+        pool.setTestWhileIdle(true);
+        pool.setEvictionPolicyClassName(TestEvictionPolicy.class.getName());
+
+        Object[] active = new Object[500];
+        for(int i=0;i<500;i++) {
+            active[i] = pool.borrowObject();
+        }
+        for(int i=0;i<500;i++) {
+            pool.returnObject(active[i]);
+        }
+
+        try { Thread.sleep(1000L); } catch(InterruptedException e) { }
+        assertEquals("Should be 500 idle", 500, pool.getNumIdle());
+        try { Thread.sleep(1000L); } catch(InterruptedException e) { }
+        assertEquals("Should be 0 idle", 0, pool.getNumIdle());
+    }
+ 
+
     @Test(timeout=60000)
     public void testEvictionSoftMinIdle() throws Exception {
         class TimeTest extends BasePoolableObjectFactory<TimeTest> {