This is an automated email from the ASF dual-hosted git repository. psteitz pushed a commit to branch POOL_2_X in repository https://gitbox.apache.org/repos/asf/commons-pool.git
The following commit(s) were added to refs/heads/POOL_2_X by this push: new 02ea9f47 JIRA: POOL-421. GenericObjectPool addObject should return immediately when there is no capacity to add. 02ea9f47 is described below commit 02ea9f47602e1828b69a4f7a0a450c106473fa7b Author: Phil Steitz <phil.ste...@gmail.com> AuthorDate: Wed May 21 14:42:45 2025 -0700 JIRA: POOL-421. GenericObjectPool addObject should return immediately when there is no capacity to add. --- src/changes/changes.xml | 1 + .../apache/commons/pool2/impl/GenericObjectPool.java | 6 +++++- .../commons/pool2/impl/TestGenericObjectPool.java | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index bfe6183d..8c5b0d0e 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -47,6 +47,7 @@ The <action> type attribute can be add,update,fix,remove. <body> <release version="2.12.2" date="YYYY-MM-DD" description="This is a feature and maintenance release. Java 8 or later is required."> <!-- FIX --> + <action type="fix" issue="POOL-421" dev="psteitz" due-to="Phil Steitz">GenericObjectPool addObject should return immediately when there is no capacity to add.</action> <action type="fix" issue="POOL-420" dev="psteitz" due-to="Phil Steitz">The maximum wait time for GenericKeyedObjectPool.borrowObject(*) may exceed configured maximum wait time. This is the same issue as POOL-418, but for GKOP. Also included in this fix is a change to addObject that prevents it from waiting for capacity to create. That method now returns immediately when there is no capcity to add to the pool under the given key. </action> 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 f20292bb..18caa97e 100644 --- a/src/main/java/org/apache/commons/pool2/impl/GenericObjectPool.java +++ b/src/main/java/org/apache/commons/pool2/impl/GenericObjectPool.java @@ -211,7 +211,11 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> if (factory == null) { throw new IllegalStateException("Cannot add objects without a factory."); } - addIdleObject(create(getMaxWaitDuration())); + + final int localMaxTotal = getMaxTotal(); + if (localMaxTotal < 0 || createCount.get() < localMaxTotal) { + addIdleObject(create(getMaxWaitDuration())); + } } /** 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 c2dc162e..a258433d 100644 --- a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java +++ b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java @@ -2886,4 +2886,21 @@ public class TestGenericObjectPool extends TestBaseObjectPool { assertEquals(1, genericObjectPool.getNumIdle()); genericObjectPool.close(); } + + @Test + @Timeout(value = 400, unit = TimeUnit.MILLISECONDS) + public void testAddObjectFastReturn() throws Exception { + final SimpleFactory simpleFactory = new SimpleFactory(); + simpleFactory.makeLatency = 500; + final GenericObjectPool<String> pool = new GenericObjectPool<>(simpleFactory); + pool.setMaxTotal(1); + pool.setBlockWhenExhausted(true); + pool.setMaxWait(Duration.ofMillis(1000)); + // Start a test thread. The thread will trigger a create, which will take 500 ms to complete + final TestThread<String> thread = new TestThread<>(pool); + final Thread t = new Thread(thread); + t.start(); + Thread.sleep(50); // Wait for the thread to start + pool.addObject(); // Should return immediately + } }