javaobject-poolingapache-commons-pool

Apache Pool 2 - predefined object instances with fixed capacity


I would like to use Apache Pool 2 library, but looking for following functionality:

  1. The objects are not dummy new empty instances, but pre-loaded objects from external data source. You can imagine each object is unique working configuration which can be passed to generic task and such task will work. I don't need to clean up object, just return them.
  2. The number of objects in pool is fixed.

Isn't it better to write my own pool or is there way to achieve this with apache?

Or is there some better pattern to be used?


Solution

  • Ok, I followed the example on the site of Apache Pool and also investigated the documentation, but I really didn't find a way about how to push into pool my previously created object, so the only way I found work although really ugly was to: 1. Get dummy empty object from the pool in one loop and put them to external ArrayList 2. Loop over List and set objects and return those into the pool

    After I try to obtain the object from the pool with following implementation those keep its setting which is behaviour as expected, but I would like to rather use factory to crate PooledObject which I can push somehow to pool. I tried use() of pool object, or wrap() method of genericobjectfactory, but it doesn't work as I expected it to work. So following code works as expected, sorry it is ugly as I just tested the functionality:

    public class ProxyMetadata  {
    
        public static Logger LOG = LogManager.getLogger(ProxyMetadata.class);
        public static List<Proxy> PROXIES = new ArrayList<>();
        public static int PROXIES_AVAILABLE;
    
        private static ProxyBufferFactory proxyBufferFactory = new ProxyBufferFactory();
        private static GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        private static GenericObjectPool<Proxy> pool;
        //Pool<Proxy> pool = new BoundedBlockingPool< Proxy >();
    
    
        void init() {
            final List<Proxy> availableProxies = getAvailableProxies();
            genericObjectPoolConfig.setMaxTotal(PROXIES_AVAILABLE);
            genericObjectPoolConfig.setBlockWhenExhausted(true);
            genericObjectPoolConfig.setTestOnBorrow(true);
            //pool = new BoundedBlockingPool< Proxy >();
            pool = new GenericObjectPool<Proxy>(proxyBufferFactory,genericObjectPoolConfig);
            List<Proxy> initializator = new ArrayList<>();
            LOG.debug("Pool management starting...");
            LOG.debug("Pool start idle:" + pool.getNumIdle());
            LOG.debug("Pool start active:" + pool.getNumActive());
            for (int i= 0; i < PROXIES_AVAILABLE; i++){
                try {
    
                    //final Proxy proxy = new Proxy();
                    final Proxy proxy = pool.borrowObject();
                    proxy.setProxyHost(String.valueOf(i));
                    //proxyBufferFactory.wrap(proxy);
                    initializator.add(proxy);
                    //pool.returnObject(proxy);
                    LOG.debug("Pool idle - loop " + String.valueOf(i)+ ": " + pool.getNumIdle());
                    LOG.debug("Pool active - loop"+ String.valueOf(i) + ": " + pool.getNumActive());
    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            LOG.debug("ALL PROXIES BORROWED");
            LOG.debug("Pool after borrow idle:" + pool.getNumIdle());
            LOG.debug("Pool after borrow active:" + pool.getNumActive());
            LOG.debug("Going to return");
            for (Proxy proxy : initializator){
                pool.returnObject(proxy);
                LOG.debug("Pool after return idle:" + pool.getNumIdle());
                LOG.debug("Pool after return active:" + pool.getNumActive());
            }
    
            LOG.debug("Clearing buffer: " + initializator.size());
            initializator.clear();
            LOG.debug("Clearing buffer: " + initializator.size());
            LOG.debug("Pool status before reborrow.");
            LOG.debug("Pool idle:" + pool.getNumIdle());
            LOG.debug("Pool active:" + pool.getNumActive());
            for (int i= 0; i < PROXIES_AVAILABLE; i++){
                try {
    
                    final Proxy proxy = pool.borrowObject();
    
                    LOG.debug("Pool idle:" + pool.getNumIdle());
                    LOG.debug("Pool active:" + pool.getNumActive());
                    LOG.debug("Borrowed final proxy:" + proxy.toString());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    

    Here is log output where can be seen that again borrowed objects which were initially borrowed and configured are available:

    Pool management starting...
    Pool start idle:0
    Pool start active:0
    Pool idle - loop 0: 0
    Pool active - loop0: 1
    Pool idle - loop 1: 0
    Pool active - loop1: 2
    Pool idle - loop 2: 0
    Pool active - loop2: 3
    ALL PROXIES BORROWED
    Pool after borrow idle:0
    Pool after borrow active:3
    Going to return
    Pool after return idle:1
    Pool after return active:2
    Pool after return idle:2
    Pool after return active:1
    Pool after return idle:3
    Pool after return active:0
    Clearing buffer: 3
    Clearing buffer: 0
    Pool status before reborrow.
    Pool idle:3
    Pool active:0
    Pool idle:2
    Pool active:1
    Borrowed final proxy:Proxy(proxyHost=2, proxyPort=null, proxyUser=null, proxyPassword=null, geoIPLocation=null, isAvailable=true)
    Pool idle:1
    Pool active:2
    Borrowed final proxy:Proxy(proxyHost=1, proxyPort=null, proxyUser=null, proxyPassword=null, geoIPLocation=null, isAvailable=true)
    Pool idle:0
    Pool active:3
    Borrowed final proxy:Proxy(proxyHost=0, proxyPort=null, proxyUser=null, proxyPassword=null, geoIPLocation=null, isAvailable=true)
    
        Process finished with exit code 0
    

    So the behaviour is as expected, but I would simply extend the pool with put() method of the PooledObject as parameter, so you can initialize pool in more intuitive way...