javaapache-commonsobject-poolingapache-commons-pool

Keyed object pool not keeping minimum number of idle objects in pool at all times


An application I'm working on, uses the Apache Commons library to implement the KeyedObjectPools.

We have an Object factory, wherein we have implemented the methods specified in the KeyedPoolObjectFactory interface. The implementation looks like this:

class MyKeyedPooledObjectFactory implements KeyedPooledObjectFactory<myKey, myObject> {

    makeObject(key) {
          //things that make myObject and
          //return DefaultPooledObject<>(myObject)
    }
    activateObject(key, pooledObject) {
        log.info("Activating object for {}", key)
    }

    passivateObject(key, pooledObject) {
        log.info("Passivating object for {}", key)
        pooledObject.getObject().someMethodToResetObject()
    }
    destroyObject(key, pooledObject) {
        log.info("Destroying object for {}", key)
    }
    validateObject(key, pooledObject) { // never gets called in code
        return true; 
    }
}

Until recently default configurations were being used to construct the keyed object pool. Now, I have changed to using a modified configuration as follows:

  1. TimeBetweenEvictionRunsMillis = 300000 (it is set to 5 minutes and idle object eviction thread is enabled)
  2. MinIdlePerKey = 1 (I need to keep at least 1 object per key in the pool at all times to satisfy our latency requirements)
  3. MinEvictableIdleTimeMillis = 300000 (i.e., object can remain idle in the pool for 5 minutes, following which it becomes eligible for eviction)

(The other configurations remain the same, i.e., default values)

Now while I run the application, I see that the eviction thread is running and within 10 minutes of object remaining idle, the destroyObject() method is being called as expected. But, I also notice that the pool is not maintaining a minimum of 1 idle object per key.

My understanding is that there is a mechanism to ensure that a minimum number of objects per key will be available if minIdlePerKey is set. But this does not seem to be happening, and I'm unable to figure out the cause for the same.

Any help or insights on why this is happening would be really useful.

The only caveat I see is, I'm referring to documentation api-1.6 documentation while, using the methods from api-2.0. I have used poolConfig.setMinIdlePerKey(myMinIdlePerKeyValue) which should be the equivalent to poolConfig.setMinIdle() in the 1.6 version.


Solution

  • minEvictableIdleTimeMillis does not honor the minIdle, what you are looking for is softMinEvictableIdleTimeMillis. Refer to the below documentation :

    https://commons.apache.org/proper/commons-pool/apidocs/org/apache/commons/pool2/impl/BaseGenericObjectPool.html#setSoftMinEvictableIdleTimeMillis(long)

    However, do note that if minEvictableIdleTimeMillis is set, softMinEvictableIdleTimeMillis is ignored.