[ 
https://issues.apache.org/jira/browse/POOL-419?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17923370#comment-17923370
 ] 

Raju Gupta edited comment on POOL-419 at 2/3/25 11:12 PM:
----------------------------------------------------------

Hi [~ggregory]. Hope you are well. I really thought about your comment last 
year to focus on bug fixes. I have tried my best.

I have created a PR at [https://github.com/apache/commons-pool/pull/385]
 * The PR adds a test to demonstrate that the value of getMaxActive can be a 
negative number.
 * The PR also proposes a solution to fix this issue.

During my debugging, I found that when the returned objects were being added 
back to the queue of the idle objects, there was a possibility where they could 
have been invalidated by another thread leading to invalid objects being added 
back to the queue of the idle objects which is not desirable.

I am eager to know you critical thoughts on this. Thanks!


was (Author: JIRAUSER308107):
Hi [~ggregory]. Hope you are well. I really thought about your comment last 
year to focus on bug fixes. I have tried my best.

I have created a PR at 
[https://github.com/apache/commons-pool/pull/385|https://github.com/apache/commons-pool/pull/385]
 * The PR adds a test to demonstrate that the value of getMaxActive can be a 
negative number.
 * The PR also proposes a solution to fix this issue.

During my debugging, I found that when the returned objects were being added 
back to the set of the idle objects, there was a possibility where they could 
have been invalidated by another thread leading to invalid objects being added 
back to the pool which is not desirable.

I am eager to know you critical thoughts on this. Thanks!

> GenericObjectPoolConfig getNumActive return negative value
> ----------------------------------------------------------
>
>                 Key: POOL-419
>                 URL: https://issues.apache.org/jira/browse/POOL-419
>             Project: Commons Pool
>          Issue Type: Bug
>    Affects Versions: 2.12.0
>            Reporter: john ms
>            Priority: Major
>
> We've notice unexpected counting that is return from getNumActive .
> and it means that allObjects and idleObjects are out of sync.
> Calling returnObject and invalidateObject on the same pooled object from two 
> different threads is causing  getNumActive to return negative value. 
> Why two threads are working on the same object at the same time and the real 
> running use case is much complex to described and not relevant, I think.  
> Bellow is a simple program to demo the behavior 
> {*}Expected result{*}: 
> getNumActive=0
>  
> {*}Actual result{*}: 
> getNumActive=\{negative number}
> If it help debugging the RC, I've notice that returnObject is not 
> synchronized over pooled object and verify it's status before using it, like 
> it's done in invalidateObject. 
> {*}Workaround{*}:
> Synchronize the  pooled object before calling returnObject/invalidateObject 
>  
> Java 17
> {code:java}
> public class PoolObject extends BasePooledObjectFactory<PoolObject> {
>     @Override
>     public PoolObject create() {
>         return new PoolObject();
>     }
>     @Override
>     public PooledObject<PoolObject> wrap(PoolObject poolObject) {
>         return new DefaultPooledObject<>(poolObject);
>     }
>     @Override
>     public void passivateObject(PooledObject<PoolObject> pooledObject) {
>     }
> }{code}
>  
> {code:java}
> public static void main (String [] args) throws Exception {
>     ExecutorService executor = Executors.newCachedThreadPool();
>     GenericObjectPoolConfig<PoolObject> poolConfig = new 
> GenericObjectPoolConfig<>();
>     poolConfig.setMaxTotal(200000);
>     poolConfig.setMaxIdle(200000);
>     poolConfig.setMinIdle(200000);
>     ObjectPool<PoolObject> objectPool = new GenericObjectPool<>(new 
> PoolObject(), poolConfig);
>     for (int i=0; i<1000000; i++){
>        PoolObject poolObject= objectPool.borrowObject();
>        FutureTask invalidateObject = new FutureTask<>(() -> {
>           Thread.sleep(RandomUtils.nextInt(0,10));
>           //synchronized (poolObject) { // Workaround bug
>              objectPool.invalidateObject(poolObject);
>           //}
>           return true;
>        });
>        executor.execute(invalidateObject);
>        FutureTask returnObject = new FutureTask<>(() -> {
>           Thread.sleep(RandomUtils.nextInt(0,10));
>           //synchronized (poolObject) { // Workaround bug
>              objectPool.returnObject(poolObject);
>           //}
>           return true;
>        });
>        executor.execute(returnObject);
>     }
>     Thread.sleep(2000);
>     executor.shutdown();
>     System.out.println("getNumActive=" + objectPool.getNumActive());
> }{code}
>  
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to