4 Replies Latest reply: Jun 30, 2011 4:15 PM by ciezadlo RSS

maxIdle Problem : EJB v/s MBean : 4.2.1.FINAL

Nathan Ciliberto Newbie

We are having a problem with a cache with maxIdle set.

After the maxIdle is "reached" the cache in effect becomes "readonly".

 

In addition, after the maxIdle time is reached the cache contents can be read by calls from an EJB, but not from an MBean.

(I have verified via a heap dump that there are no duplicate caches, btw.)

 

We are using version 4.2.1.FINAL, but we had the same problem with the previous release.

We are using jbossAS 6.0.0.Final "Neo".

 

Our cache has maxIdle set to 2 hours.

It is implemented as a TreeCache (org.infinispan.tree.TreeCache).

It is setup to cluster to one other jboss server (which is currently shutdown).

 

Most of the time we have applications hitting this every 10 minutes.

So in effect the nodes should "never" expire... i.e. the maxIdle should never be reached for these nodes.

 

However, there are times when the cache needs to be updated.

In order to update the cache we first clear it, then reload the data into the cache.

 

The only way to clear the cache is to use a combination of calls:

 

    Set nodes = myCache.getRoot().getChildren();

    Iterator it = nodes.iterator();

    while(it.hasNext())

    {

        Node node = (Node)it.next();

        myCache.removeNode( node.getFqn() );

        node = null;

    }

    myCache.getRoot().removeChildren();

    myCache.removeNode(Fqn.ROOT);

    myCache.getCache().clear();

 

When the maxIdle is "reached" the getRoot().getChildren() method returns an empty set.

The getCache().clear() method appears to be the only thing that is removing the nodes when the "maxIdle" is reached.

(again... the the nodes should never actually reach the "maxIdle" timeout)

 

This "clearing" is done by the EJB's (which are Stateless), not by an MBean.

 

 

 

Our MBean is used to view the cache contents.

 

Our tree structure is like:

 

    /nodeA/keyA = some-data-for-A

    /nodeA/keyB = some-data-for-B

    /nodeA/keyC = some-data-for-C

    ...

    /nodeX/keyX = some-data-for-X

    /nodeX/keyY = some-data-for-Y

    /nodeX/keyZ = some-data-for-Z

 

So keys A, B & C are all under nodeA and X, Y & Z are all under nodeX.

 

In order to retrieve the values to display we have to do:

 

    Node        root    = myCache.getRoot()

    Set<Node>   nodes   = root.getChildren();

    for( Node node : nodes ){

        Set keys        = node.getKeys();

        Set children    = node.getChildren();

 

        if( null != keys || null != children ){

            LinkedList llKeys = new LinkedList();

            if( null != keys ){

                llKeys.addAll( keys );

            }

            if( null != children ){

                llKeys.addAll( children );

            }

            Collection objColl;

            for( Object key : objColl ){

                if( key instanceof Node ){

                    Node myNode = (Node) key ;

                    Object value = myNode.getData();

                    // display value

                }else{

                    Object value = node.get( key );

                    // display value

                }

            }

        }else{

            // nothing found

        }

    }

 

In the code above "keyA" and "keyX" are the ONLY key returned by "nodeA".getKeys() and "nodeX".getKeys() respectively.

Keys "keyB" & "keyC" and "keyY" & "keyZ" are ONLY returned by their nodes using "nodeA".getChildren() and "nodeX".getChildren() respectively.

Is this the expected behavior?

I would have expected getKeys() to return A, B & C and X, Y & Z not just the first one of each node...?

 

However, once the "maxIdle" is reached none of the keys/nodes are returned even though nothing should actually be "expired".

 

If I attach the debugger the cache does still contain the keys, but the calls to the cache are returning nothing.

So... it looks like it may have something to do with the transaction manager (wrt the "maxIdle" issue).

 

If the cache is cleared (using the code the EJB calls above) things work again until the maxIdle is "reached" again.

Now... the maxIdle being "reached" is an approximation.

If I set the maxIdle to 5 minutes, 10 minutes, 30 minutes or 48 hours the time it takes for the issue to appear corresponds to the shorter or longer maxIdle setting.

 

I've attached the config files we are using.