[
https://issues.apache.org/jira/browse/POOL-412?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17718079#comment-17718079
]
Oleksandr Porytskyi commented on POOL-412:
------------------------------------------
What was changed? Unfourtenately my test for GenericKeyedObjectPool still not
pass.
{code:java}
import java.time.Duration;
import org.apache.commons.pool2.BaseKeyedPooledObjectFactory;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class PoolTest {
@Test
void testGenericKeyedObjectPool() throws Exception {
BaseKeyedPooledObjectFactory<String, Object, Exception>
baseKeyedPooledObjectFactory = new BaseKeyedPooledObjectFactory<>() {
@Override
public Object create(String key) throws Exception {
return new Object();
}
@Override
public PooledObject<Object> wrap(Object value) {
return new DefaultPooledObject<>(value);
}
};
GenericKeyedObjectPoolConfig<Object> genericKeyedObjectPoolConfig = new
GenericKeyedObjectPoolConfig<>();
int minIdlePerKey = 1;
genericKeyedObjectPoolConfig.setTimeBetweenEvictionRuns(Duration.ofSeconds(1));
genericKeyedObjectPoolConfig.setMinIdlePerKey(minIdlePerKey);
genericKeyedObjectPoolConfig.setMinEvictableIdleTime(Duration.ofSeconds(5));
GenericKeyedObjectPool<String, Object, Exception> genericKeyedObjectPool =
new GenericKeyedObjectPool<>(
baseKeyedPooledObjectFactory, genericKeyedObjectPoolConfig);
String key = "key";
genericKeyedObjectPool.preparePool(key);
Assertions.assertTimeoutPreemptively(Duration.ofMinutes(1), () -> {
while (genericKeyedObjectPool.getNumIdle(key) != minIdlePerKey)
;
});
System.out.println("we prepared pool so we have idle");
Assertions.assertTimeoutPreemptively(Duration.ofMinutes(1), () -> {
while (genericKeyedObjectPool.getNumIdle(key) != 0)
;
});
System.out.println("after eviction we have no idle");
Assertions.assertTimeoutPreemptively(Duration.ofMinutes(1), () -> {
while (genericKeyedObjectPool.getNumIdle(key) != minIdlePerKey)
;
});
System.out.println("NEVER HAPPEN: after eviction ensure min idle");
}
@Test
void testGenericObjectPool() throws Exception {
BasePooledObjectFactory<Object, Exception> basePooledObjectFactory = new
BasePooledObjectFactory<>() {
@Override
public Object create() throws Exception {
return new Object();
}
@Override
public PooledObject<Object> wrap(Object obj) {
return new DefaultPooledObject<>(obj);
}
};
GenericObjectPoolConfig<Object> genericObjectPoolConfig = new
GenericObjectPoolConfig<>();
int minIdle = 1;
genericObjectPoolConfig.setTimeBetweenEvictionRuns(Duration.ofSeconds(1));
genericObjectPoolConfig.setMinIdle(minIdle);
genericObjectPoolConfig.setMinEvictableIdleTime(Duration.ofSeconds(5));
GenericObjectPool<Object, Exception> genericObjectPool = new
GenericObjectPool<>(
basePooledObjectFactory,
genericObjectPoolConfig);
genericObjectPool.preparePool();
Assertions.assertTimeoutPreemptively(Duration.ofMinutes(1), () -> {
while (genericObjectPool.getNumIdle() != minIdle)
;
});
System.out.println("we prepared pool so we have idle");
Assertions.assertTimeoutPreemptively(Duration.ofMinutes(1), () -> {
while (genericObjectPool.getNumIdle() != 0)
;
});
System.out.println("after eviction we have no idle");
Assertions.assertTimeoutPreemptively(Duration.ofMinutes(1), () -> {
while (genericObjectPool.getNumIdle() != minIdle)
;
});
System.out.println("after eviction ensure min idle");
}
}
{code}
I used snapshot build.
> [GenericKeyedObjectPool] ensureMinIdle not work if last idle evicted
> --------------------------------------------------------------------
>
> Key: POOL-412
> URL: https://issues.apache.org/jira/browse/POOL-412
> Project: Commons Pool
> Issue Type: Bug
> Affects Versions: 2.11.1
> Reporter: Oleksandr Porytskyi
> Priority: Major
>
> I'm trying to use GenericKeyedObjectPool with setMinIdlePerKey(1) and
> setTestWhileIdle(true). When object failed validation it is removed but
> never add new one.
> Evictor has two stages:
> 1. In evict() call destroy() -> deregister(key) -> poolMap.remove(k)
> For some reason it removes key if there are no more objects of it.
>
> 2. In ensureMinIdle() ->
> for (final K k : poolMap.keySet()) {
> ensureMinIdle(k);
> }
> poolMap does not have my key anymore so will not create object for it.
>
> Here one test for GenericObjectPool which pass and one for
> GenericKeyedObjectPool which not pass for same scenario:
> {code:java}
> @Test
> void testGenericKeyedObjectPool() throws Exception {
> BaseKeyedPooledObjectFactory<String, Object> baseKeyedPooledObjectFactory =
> new BaseKeyedPooledObjectFactory<>() {
> @Override
> public Object create(String key) throws Exception {
> return null;
> }
> @Override
> public PooledObject<Object> wrap(Object value) {
> return new DefaultPooledObject<>(value);
> }
> };
> GenericKeyedObjectPoolConfig<Object> genericKeyedObjectPoolConfig = new
> GenericKeyedObjectPoolConfig<>();
> int minIdlePerKey = 1;
> genericKeyedObjectPoolConfig.setMinIdlePerKey(minIdlePerKey);
>
> genericKeyedObjectPoolConfig.setTimeBetweenEvictionRuns(Duration.ofSeconds(1));
> genericKeyedObjectPoolConfig.setMinEvictableIdleTime(Duration.ofSeconds(5));
> GenericKeyedObjectPool<String, Object> genericKeyedObjectPool = new
> GenericKeyedObjectPool<>(
> baseKeyedPooledObjectFactory, genericKeyedObjectPoolConfig);
> String key = "key";
> genericKeyedObjectPool.preparePool(key);
> Assertions.assertTimeoutPreemptively(Duration.ofMinutes(1), () -> {
> while (genericKeyedObjectPool.getNumIdle(key) != minIdlePerKey)
> ;
> });
> System.out.println("we prepared pool so we have idle");
> Assertions.assertTimeoutPreemptively(Duration.ofMinutes(1), () -> {
> while (genericKeyedObjectPool.getNumIdle(key) != 0)
> ;
> });
> System.out.println("after eviction we have no idle");
> Assertions.assertTimeoutPreemptively(Duration.ofMinutes(1), () -> {
> while (genericKeyedObjectPool.getNumIdle(key) != minIdlePerKey)
> ;
> });
> System.out.println("NEVER HAPPEN: after eviction ensure min idle");
> }
> @Test
> void testGenericObjectPool() throws Exception {
> BasePooledObjectFactory<Object> basePooledObjectFactory = new
> BasePooledObjectFactory<>() {
> @Override
> public Object create() throws Exception {
> return null;
> }
> @Override
> public PooledObject<Object> wrap(Object obj) {
> return new DefaultPooledObject<>(obj);
> }
> };
> GenericObjectPoolConfig<Object> genericObjectPoolConfig = new
> GenericObjectPoolConfig<>();
> int minIdle = 1;
> genericObjectPoolConfig.setTimeBetweenEvictionRuns(Duration.ofSeconds(1));
> genericObjectPoolConfig.setMinIdle(minIdle);
> genericObjectPoolConfig.setMinEvictableIdleTime(Duration.ofSeconds(5));
> GenericObjectPool<Object> genericObjectPool = new
> GenericObjectPool<>(basePooledObjectFactory,
> genericObjectPoolConfig);
> genericObjectPool.preparePool();
> Assertions.assertTimeoutPreemptively(Duration.ofMinutes(1), () -> {
> while (genericObjectPool.getNumIdle() != minIdle)
> ;
> });
> System.out.println("we prepared pool so we have idle");
> Assertions.assertTimeoutPreemptively(Duration.ofMinutes(1), () -> {
> while (genericObjectPool.getNumIdle() != 0)
> ;
> });
> System.out.println("after eviction we have no idle");
> Assertions.assertTimeoutPreemptively(Duration.ofMinutes(1), () -> {
> while (genericObjectPool.getNumIdle() != minIdle)
> ;
> });
> System.out.println("after eviction ensure min idle");
> }
> {code}
> As workaround I can't just subclass GenericKeyedObjectPool and alter
> deregister as it private.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)