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 2018/05/21 11:56:39 UTC

[1/2] commons-pool git commit: Ignore bin (local IDE directory)

Repository: commons-pool
Updated Branches:
  refs/heads/master 5a30c6e9c -> 867614829


Ignore bin (local IDE directory)


Project: http://git-wip-us.apache.org/repos/asf/commons-pool/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-pool/commit/87683a59
Tree: http://git-wip-us.apache.org/repos/asf/commons-pool/tree/87683a59
Diff: http://git-wip-us.apache.org/repos/asf/commons-pool/diff/87683a59

Branch: refs/heads/master
Commit: 87683a59c4cf3b7c2c60b75c271d8738c4501233
Parents: 5a30c6e
Author: Mark Thomas <ma...@apache.org>
Authored: Mon May 21 12:38:45 2018 +0100
Committer: Mark Thomas <ma...@apache.org>
Committed: Mon May 21 12:46:23 2018 +0100

----------------------------------------------------------------------
 .gitignore | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-pool/blob/87683a59/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index af579fe..35c0dd0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ site-content
 /.classpath
 /.project
 /.settings/
+/bin/


[2/2] commons-pool git commit: Fix POOL-337. Ensure cancelled eviction tasks are removed from scheduler. Includes a test case based on a patch by Reinald Verheij.

Posted by ma...@apache.org.
Fix POOL-337. Ensure cancelled eviction tasks are removed from scheduler. Includes a test case based on a patch by Reinald Verheij.


Project: http://git-wip-us.apache.org/repos/asf/commons-pool/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-pool/commit/86761482
Tree: http://git-wip-us.apache.org/repos/asf/commons-pool/tree/86761482
Diff: http://git-wip-us.apache.org/repos/asf/commons-pool/diff/86761482

Branch: refs/heads/master
Commit: 867614829ba6b041ca6becbad0f43cb180003404
Parents: 87683a5
Author: Mark Thomas <ma...@apache.org>
Authored: Mon May 21 12:45:18 2018 +0100
Committer: Mark Thomas <ma...@apache.org>
Committed: Mon May 21 12:51:17 2018 +0100

----------------------------------------------------------------------
 src/changes/changes.xml                         |   3 +
 .../pool2/impl/BaseGenericObjectPool.java       |  16 ++-
 .../commons/pool2/impl/EvictionTimer.java       |  19 ++--
 .../commons/pool2/impl/TestEvictionTimer.java   | 105 +++++++++++++++++++
 4 files changed, 133 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-pool/blob/86761482/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index d0255c6..13227ee 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -50,6 +50,9 @@ The <action> type attribute can be add,update,fix,remove.
     <action dev="ggregory" issue="POOL-339" type="update">
       Update optional library cglib from 3.2.5 to 3.2.6.
     </action>
+    <action dev="markt" issue="POOL-337" type="fix" due-to="Reinald Verheij">
+      Ensure cancelled eviction tasks are removed from scheduler.
+    </action>
   </release>
   <release version="2.5.0" date="2017-12-16" description="This is a minor release, updating to Java 7.">
     <action dev="ggregory" issue="POOL-331" type="update">

http://git-wip-us.apache.org/repos/asf/commons-pool/blob/86761482/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java b/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
index d9a4df7..bd3e80b 100644
--- a/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
+++ b/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
@@ -26,6 +26,7 @@ import java.util.Arrays;
 import java.util.Deque;
 import java.util.Iterator;
 import java.util.TimerTask;
+import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -1026,7 +1027,10 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
      *
      * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
      */
-    class Evictor extends TimerTask {
+    class Evictor implements Runnable {
+
+        private ScheduledFuture<?> scheduledFuture;
+
         /**
          * Run pool maintenance.  Evict objects qualifying for eviction and then
          * ensure that the minimum number of idle instances are available.
@@ -1074,6 +1078,16 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
                 Thread.currentThread().setContextClassLoader(savedClassLoader);
             }
         }
+
+
+        void setScheduledFuture(ScheduledFuture<?> scheduledFuture) {
+            this.scheduledFuture = scheduledFuture;
+        }
+
+
+        void cancel() {
+            scheduledFuture.cancel(false);
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/commons-pool/blob/86761482/src/main/java/org/apache/commons/pool2/impl/EvictionTimer.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/pool2/impl/EvictionTimer.java b/src/main/java/org/apache/commons/pool2/impl/EvictionTimer.java
index 0b5e3ac..bc0a5ff 100644
--- a/src/main/java/org/apache/commons/pool2/impl/EvictionTimer.java
+++ b/src/main/java/org/apache/commons/pool2/impl/EvictionTimer.java
@@ -19,6 +19,7 @@ package org.apache.commons.pool2.impl;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.TimerTask;
+import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.TimeUnit;
@@ -44,9 +45,6 @@ class EvictionTimer {
     /** Executor instance */
     private static ScheduledThreadPoolExecutor executor; //@GuardedBy("EvictionTimer.class")
 
-    /** Static usage count tracker */
-    private static int usageCount; //@GuardedBy("EvictionTimer.class")
-
     /** Prevent instantiation */
     private EvictionTimer() {
         // Hide the default constructor
@@ -73,12 +71,15 @@ class EvictionTimer {
      * @param delay     Delay in milliseconds before task is executed
      * @param period    Time in milliseconds between executions
      */
-    static synchronized void schedule(final Runnable task, final long delay, final long period) {
+    static synchronized void schedule(
+            final BaseGenericObjectPool<?>.Evictor task, final long delay, final long period) {
         if (null == executor) {
             executor = new ScheduledThreadPoolExecutor(1, new EvictorThreadFactory());
+            executor.setRemoveOnCancelPolicy(true);
         }
-        usageCount++;
-        executor.scheduleWithFixedDelay(task, delay, period, TimeUnit.MILLISECONDS);
+        ScheduledFuture<?> scheduledFuture =
+                executor.scheduleWithFixedDelay(task, delay, period, TimeUnit.MILLISECONDS);
+        task.setScheduledFuture(scheduledFuture);
     }
 
     /**
@@ -90,10 +91,10 @@ class EvictionTimer {
      *                  terminate?
      * @param unit      The units for the specified timeout
      */
-    static synchronized void cancel(final TimerTask task, final long timeout, final TimeUnit unit) {
+    static synchronized void cancel(
+            final BaseGenericObjectPool<?>.Evictor task, final long timeout, final TimeUnit unit) {
         task.cancel();
-        usageCount--;
-        if (usageCount == 0) {
+        if (executor.getQueue().size() == 0) {
             executor.shutdown();
             try {
                 executor.awaitTermination(timeout, unit);

http://git-wip-us.apache.org/repos/asf/commons-pool/blob/86761482/src/test/java/org/apache/commons/pool2/impl/TestEvictionTimer.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/pool2/impl/TestEvictionTimer.java b/src/test/java/org/apache/commons/pool2/impl/TestEvictionTimer.java
new file mode 100644
index 0000000..97d8bdd
--- /dev/null
+++ b/src/test/java/org/apache/commons/pool2/impl/TestEvictionTimer.java
@@ -0,0 +1,105 @@
+/*
+ * 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.commons.pool2.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import java.lang.reflect.Field;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.pool2.BasePooledObjectFactory;
+import org.apache.commons.pool2.PooledObject;
+import org.junit.Test;
+
+/**
+ * Tests for {@link EvictionTimer}.
+ */
+public class TestEvictionTimer {
+
+    @Test
+    public void testStartStopEvictionTimer() throws Exception {
+
+        try (final GenericObjectPool<String> pool = new GenericObjectPool<>(new BasePooledObjectFactory<String>() {
+
+            @Override
+            public String create() throws Exception {
+                return null;
+            }
+
+            @Override
+            public PooledObject<String> wrap(final String obj) {
+                return new DefaultPooledObject<>(obj);
+            }
+        })) {
+
+            // Start evictor #1
+            final BaseGenericObjectPool<String>.Evictor evictor1 = pool.new Evictor();
+            EvictionTimer.schedule(evictor1, 60000, 60000);
+
+            // Assert that eviction objects are correctly allocated
+            // 1 - the evictor timer task is created
+            final Field evictorTaskFutureField =
+                    evictor1.getClass().getDeclaredField("scheduledFuture");
+            evictorTaskFutureField.setAccessible(true);
+            ScheduledFuture<?> sf = (ScheduledFuture<?>) evictorTaskFutureField.get(evictor1);
+            assertFalse(sf.isCancelled());
+            // 2- and, the eviction action is added to executor thread pool
+            final Field evictorExecutorField = EvictionTimer.class.getDeclaredField("executor");
+            evictorExecutorField.setAccessible(true);
+            final ThreadPoolExecutor evictionExecutor = (ThreadPoolExecutor) evictorExecutorField.get(null);
+            assertEquals(1, evictionExecutor.getQueue().size());
+
+            // Start evictor #2
+            final BaseGenericObjectPool<String>.Evictor evictor2 = pool.new Evictor();
+            EvictionTimer.schedule(evictor2, 60000, 60000);
+
+            // Assert that eviction objects are correctly allocated
+            // 1 - the evictor timer task is created
+            sf = (ScheduledFuture<?>) evictorTaskFutureField.get(evictor2);
+            assertFalse(sf.isCancelled());
+            // 2- and, the eviction action is added to executor thread pool
+            assertEquals(2, evictionExecutor.getQueue().size());
+
+            // Stop evictor #1
+            EvictionTimer.cancel(evictor1, BaseObjectPoolConfig.DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT_MILLIS,
+                    TimeUnit.MILLISECONDS);
+
+            // Assert that eviction objects are correctly cleaned
+            // 1 - the evictor timer task is cancelled
+            sf = (ScheduledFuture<?>) evictorTaskFutureField.get(evictor1);
+            assertTrue(sf.isCancelled());
+            // 2- and, the eviction action is removed from executor thread pool
+            final ThreadPoolExecutor evictionExecutorOnStop = (ThreadPoolExecutor) evictorExecutorField.get(null);
+            assertEquals(1, evictionExecutorOnStop.getQueue().size());
+
+            // Stop evictor #2
+            EvictionTimer.cancel(evictor2, BaseObjectPoolConfig.DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT_MILLIS,
+                    TimeUnit.MILLISECONDS);
+
+            // Assert that eviction objects are correctly cleaned
+            // 1 - the evictor timer task is cancelled
+            sf = (ScheduledFuture<?>) evictorTaskFutureField.get(evictor2);
+            assertTrue(sf.isCancelled());
+            // 2- and, the eviction thread pool executor is freed
+            assertNull(evictorExecutorField.get(null));
+        }
+    }
+}
\ No newline at end of file