You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2018/07/22 14:41:18 UTC

commons-pool git commit: [POOL-347] borrowObject waits for maxWaitMillis over in pool full. Closes #10.

Repository: commons-pool
Updated Branches:
  refs/heads/master 21831143b -> 3e02523b6


[POOL-347] borrowObject waits for maxWaitMillis over in pool full.
Closes #10.

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

Branch: refs/heads/master
Commit: 3e02523b6907fb22f3582544fe362c785821bcb8
Parents: 2183114
Author: Shunsuke Nakamura <su...@gmail.com>
Authored: Sun Jul 22 08:41:14 2018 -0600
Committer: Gary Gregory <ga...@gmail.com>
Committed: Sun Jul 22 08:41:14 2018 -0600

----------------------------------------------------------------------
 src/changes/changes.xml                         |  3 ++
 .../commons/pool2/impl/GenericObjectPool.java   | 12 +++++-
 .../pool2/impl/TestGenericObjectPool.java       | 42 ++++++++++++++++++++
 3 files changed, 56 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-pool/blob/3e02523b/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index fb3d301..bee05d3 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-346" type="update" due-to="Michael Chen">
       Move common configuration setter to BaseGenericObjectPool #9.
     </action>
+    <action dev="ggregory" issue="POOL-347" type=fix" due-to="Shunsuke Nakamura">
+      borrowObject waits for maxWaitMillis over in pool full.
+    </action>
   </release>  
   <release version="2.6.0" date="2018-07-06" description="This is a maintenance release.">
     <action dev="ggregory" issue="POOL-336" type="update" due-to="Wolfgang Glas">

http://git-wip-us.apache.org/repos/asf/commons-pool/blob/3e02523b/src/main/java/org/apache/commons/pool2/impl/GenericObjectPool.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/pool2/impl/GenericObjectPool.java b/src/main/java/org/apache/commons/pool2/impl/GenericObjectPool.java
index 7ad8a5a..a05038a 100644
--- a/src/main/java/org/apache/commons/pool2/impl/GenericObjectPool.java
+++ b/src/main/java/org/apache/commons/pool2/impl/GenericObjectPool.java
@@ -822,6 +822,9 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
             localMaxTotal = Integer.MAX_VALUE;
         }
 
+        long localStartTimeMillis = System.currentTimeMillis();
+        long localMaxWaitTimeMillis = Math.max(getMaxWaitMillis(), 0);
+
         // Flag that indicates if create should:
         // - TRUE:  call the factory to create an object
         // - FALSE: return null
@@ -845,7 +848,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
                         // bring the pool to capacity. Those calls might also
                         // fail so wait until they complete and then re-test if
                         // the pool is at capacity or not.
-                        makeObjectCountLock.wait();
+                        makeObjectCountLock.wait(localMaxWaitTimeMillis);
                     }
                 } else {
                     // The pool is not at capacity. Create a new object.
@@ -853,6 +856,13 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
                     create = Boolean.TRUE;
                 }
             }
+
+            // Do not block more if maxWaitTimeMillis is set.
+            if (create == null &&
+                (localMaxWaitTimeMillis > 0 &&
+                 System.currentTimeMillis() - localStartTimeMillis >= localMaxWaitTimeMillis)) {
+                create = Boolean.FALSE;
+            }
         }
 
         if (!create.booleanValue()) {

http://git-wip-us.apache.org/repos/asf/commons-pool/blob/3e02523b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java
index baac885..b84924d 100644
--- a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java
+++ b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java
@@ -2637,6 +2637,48 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
         }
     }
 
+    @Test(timeout = 1200 /* maxWaitMillis x2 + padding */)
+    public void testReturnBorrowObjectWithingMaxWaitMillis() throws Exception {
+        long maxWaitMillis = 500;
+
+        final GenericObjectPool<String> createSlowObjectFactoryPool
+                = new GenericObjectPool<>(createSlowObjectFactory(60000));
+        createSlowObjectFactoryPool.setMaxTotal(1);
+        createSlowObjectFactoryPool.setMaxWaitMillis(maxWaitMillis);
+
+        // thread1 tries creating a slow object to make pool full.
+        final WaitingTestThread thread1 = new WaitingTestThread(createSlowObjectFactoryPool, 0);
+        thread1.start();
+
+        // Wait for thread1's reaching to create(). 
+        Thread.sleep(100);
+
+        // another one tries borrowObject. It should return within maxWaitMillis.
+        try {
+            createSlowObjectFactoryPool.borrowObject(maxWaitMillis);
+            fail("borrowObject must fail due to timeout by maxWaitMillis");
+        } catch (NoSuchElementException e) {
+        }
+
+        Assert.assertTrue(thread1.isAlive());
+    }
+
+    private BasePooledObjectFactory<String> createSlowObjectFactory(final long elapsedTimeMillis) {
+        return new BasePooledObjectFactory<String>() {
+            @Override
+            public String create() throws Exception {
+                Thread.sleep(elapsedTimeMillis);
+                return "created";
+            }
+
+            @Override
+            public PooledObject<String> wrap(final String obj) {
+                // fake
+                return new DefaultPooledObject<String>(obj);
+            }
+        };
+    }
+
     @Test
     public void testErrorFactoryDoesNotBlockThreads() throws Exception {