Pooling

iWay Service Manager offers a pooling service to simplify the pooling of objects such as connections. The basis of the pooling facility is the pool set, a facility maintained by the engine to house and monitor individual pools. Pools are shared at the system level, and in JCA situations they can be shared at the connection factory level—for example, across instances of iWay Service Manager.

There is one distinct, critical requirement for an object to be pooled. It cannot maintain stateful information between uses. A pooled object cannot rely on the information from any prior invocation or expect to be used by the same consumer during any future invocation. Pooled objects do not necessarily have to be thread safe. They just need to clean up their class variables before being returned to the pool.

Each pool (XDPool) in the set is built to house one type of item pool. Each item pooled is represented in a user-written class that extends XDPoolItem. The XDPool provides methods to set, request, and delete items from the pool. The XDPoolItem is required to implement the term() method to close down the item; term() is called by the engine for any XDPoolItem in a pool when the engine shuts down, allowing your pooling class to close. The actual XDPoolItem being pooled must represent the resource appropriately. For example, the MQ Connection pool maintains a pool by a name that relates to the thread ID, because in MQ the queue manager is thread related. The users of the pool (the XDMQEmitter) moves the item from the available queue manager connections pool to the thread pool, keyed by TID, during the time a transaction is in progress.

Each pool is given a name, by which you request the pool from the manager. If no pool exists, an empty one is created for you. You do not need to take any special action to establish the pool itself. Each pooled item is identified by its key, which can be any String. If you request a pooled item for a key that has not yet been pooled, you get a null return. At this point, you create a pool item of the key and add it to the pool.

Once you have the item, you can use the pooled object that it represents. If this is a new object, you need to set it up.

In this example, the pool holds some object of meaning (we call it MYObject) to the application.

This example pool also shows how to keep a pooled counter. One common use of a pool is to keep a named counter with no object attached.

Be careful of the scope of synchronization; the example shows how to minimize long duration locks on a central resource to avoid serializing the server.

MyObject poolUserMethod()
{
    XDPool pool;         // the pool itself
    MyPoolItem pitem;    // the specific ABC item
    int counter;
    String key = "ABC";  // id of item in the pool - first get pool by object type
    pool = worker.getPool("MYOBJECT");
    MyObject myobj;   // the copy I will work on - now use it or set it up
    synchronized (pool)
    {
        pitem = (MyPoolItem)pool.getItem(key);  // get or add
        if (pitem==null) // do I need a new one?
        {
            pitem = new MyPoolItem();
            pool.addItem(key,pitem);    // add the new object to the pool
        }
    }
    // now use the pooled item
    synchronized (pitem)
    {
        myobj = pitem.get();
        if (myobj != null)
        {
            debug("MyObject "+key+" recovered from pool");
         }
           else
           {
            counter=pitem.getHandle();  // just a serializer to show how
            myobj = new MyObject(key);  // make the object to pool
            pitem.set(myobj);
            debug("MyObject "+key+" created and added to pool");
           }
    }
           return myobj;  // ready for caller's use
   }
 // pool for MyObject instances, keyed by String
 class MyPoolItem extends XDPoolItem
 {
     boolean badItem = false;  // set if we can't connect
     int count=0;
     MyObject myobj;  // some object I am pooling
     MyPoolItem()
     {
     }
     public void term()
     {
         if (myobj != null)
         {
             try
             {
                 myobj.term(); // call my thing to shut it down
             }
             catch (Exception e)
             {
             }
         }
         myobj=null;
     }
     MyObject get()  // gets the object from the pool
     {
         return myobj;
     }
     void set(MyObject myobj) // adds the object to the pool
     {
         this.myobj = myobj;
     }
     int getHandle()    // just to show how to keep a pooled counter 
     {
         return ++count;
     } // end MyPoolItem
 } // end poolUserMethod

iWay Software