You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Gary D. Gregory (Jira)" <ji...@apache.org> on 2023/06/05 20:42:00 UTC
[jira] [Closed] (POOL-412) [GenericKeyedObjectPool] ensureMinIdle not work if last idle evicted
[ https://issues.apache.org/jira/browse/POOL-412?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Gary D. Gregory closed POOL-412.
--------------------------------
Resolution: Information Provided
> [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)