[jboss-dev-forums] [Design of JCA on JBoss] - JBAS-5929 - Idle subpools

adrian@jboss.org do-not-reply at jboss.com
Fri Sep 5 04:16:38 EDT 2008


We need a mechanism to clear up unused subpools otherwise
they could potentially grow without bounds.

The simplest mechanism I'd suggest is for the
InternalManagedConnectionPool.removeIdleConnections() to notify the
JBossManagedConnectionPool when the pool has become empty.

Problem 1: The IMCP doesn't currently hold a reference to the JMCP it belongs to.

The JBossManagedConnectionPool::BasePool can then decide whether
to remove the pool if it is subpooling, e.g.


  |       public void emptySubPool(InternalManagedConnectionPool pool)
  |       {
  |          synchronized (subPools)
  |          {
  |             for (Iterator i = subPools.values().iterator(); i.hasNext(); )
  |             {
  |                SubPoolContext subPool = (SubPoolContext) i.next();
  |                InternalManagedConnectionPool other = sub.getSubPool();
  |                if (subPool == pool && pool.isEmpty())
  |                {
  |                   pool.shutdown();
  |                   i.remove();
  |                   break;
  |                }
  |             }
  |             subPools.clear();
  |          }
  |       }
  | 

NOTE: The JBossManagedConnectionPool has to "double check"
the pool is really empty since somebody could have jumped in
and requested a connection from the pool between the empty notification
from the ICMP and the JMCP actually trying to remove it.

But see below.

Problem 2: There is still a race condition here.

The "double check" is not good enough, 
since only the subpool retrieval will be synchronized with it.

BasePool::getConnection()

  |          SubPoolContext subPool = getSubPool(key, subject, cri); // HERE! This part synchronizes on sub-pools, the rest does not.
  |          
  |          InternalManagedConnectionPool mcp = subPool.getSubPool();
  |          
  |          // Are we doing track by connection?
  |          TransactionLocal trackByTx = subPool.getTrackByTx();
  | 
  |          // Simple case
  |          if (trackByTransaction == null || trackByTx == null)
  |          {
  |             ConnectionListener cl = mcp.getConnection(subject, cri);
  |             if (traceEnabled)
  |                dump("Got connection from pool " + cl);
  |             return cl;
  |          }
  | 

So the mcp.getConnection() part could find the pool has been shutdown
by the idle remover after it retrieved the now removed sub-pool.

The simplest way to resolve this race condition would be to
implement the "retries" feature request.
https://jira.jboss.org/jira/browse/JBAS-3997
where if this race condition goes the wrong way, the connection manager
would just trap the "transient failure" and redo the request.
i.e. the pool is shutdown error would be a RetryableResourceException

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4174502#4174502

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4174502



More information about the jboss-dev-forums mailing list