[
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 10:36 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|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!
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.]
* 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)