[ 
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)

Reply via email to