2 Replies Latest reply on Sep 5, 2008 4:22 AM by adrian.brock

    JBAS-5929 - Idle subpools

      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