you didn't read the excercise I gave you did you ????
 
please read the excercise vinay it explain a much faster way to do the "invalidate".
 
(for the others, this is in fact one of the excercise we do on the last day of the training and I wrote it specifically for Vinay but it is now part of the standard class, we are now looking at making it a standard extension of JBoss.
 
Vinay what is bad about this you synchronize on the table and lock it for the time you iterate over all the elements.
 
Reread my description of it (PLEASE :)
 
I do like the fact that you put it in another interceptor.  The only problem with it is that using it will require a custom interceptor layout, you will need to externalize this in the standard JBoss wereas the basic one would have given you just "optionD" and that is it..  However I kinda like having an extra interceptor taht is a good thing.
 
Also explain to me why the home has a "register" on the tx, it is not clear from the comments
 
marc
 
-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]On Behalf Of K.V. Vinay Menon
Sent: Friday, May 11, 2001 10:52 AM
To: Dev @ JBoss
Subject: [JBoss-dev] Option D - Take One!

Hello Folks,
    Took a wild shot at the Option D, timed cache invalidation. Have put it in a separate interceptor that sits before the EntitySynchronizationInterceptor and invalidates the EntityEnterpriseContext at regular preset intervals.
 
1. There is an invalidation timer task per entity bean [I persum per-EntityEnterpriseContext maps to per bean and not per bean instance]
2. The refersh rate is currently set at 60secs but could be moved elsewhere to the jboss config xml
3. The Configuration Metadat now has an entry for option D.
4. The interceptor does NOT reload the entity. It just invalidates the cache. The entity reload is managed by the EntitySynchronizationInterceptor.
 
Does anyone want to go thru this and get back to me? It is a first cut code using this method [the previous one had some code that was junked!]. What I'd like someone to point out is
 
1. Do we need to take care of any transaction related issues in the invoke method?
2. Am adding to a hashset. Now the Context object is removed from the hashset only when the if(ctx.getId()) evaluates to null. Do we need to have any other place where we remove the context from the list of items to be invalidated? We will have the underlying database updated by other programs that are not linked into Jboss.
 
If the code is a complete pile of crap let me know and would appreciate if you could give some pointers as well as to what is incorrect and how it could be improved. At the moment it is pretty much a crude piece of code!
 
Regards
 
Vinay
/*
* JBoss, the OpenSource EJB server
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins;
 
import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.rmi.ServerException;
 
import java.util.Timer;
import java.util.TimerTask;
import java.util.HashSet;
import java.util.Iterator;
 
import javax.ejb.EJBObject;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.NoSuchEntityException;
import javax.ejb.RemoveException;
import javax.ejb.EntityBean;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
 
import org.jboss.ejb.Container;
import org.jboss.ejb.EntityContainer;
import org.jboss.ejb.EntityPersistenceManager;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.EnterpriseContext;
import org.jboss.ejb.InstanceCache;
import org.jboss.ejb.InstancePool;
import org.jboss.ejb.MethodInvocation;
import org.jboss.metadata.ConfigurationMetaData;
import org.jboss.logging.Logger;
 
public class SoftBallInterceptor
extends AbstractInterceptor
{
    protected int commitOption;
    protected EntityContainer container;
    protected HashSet ctxToInvalidate = new HashSet();
    private static int REFRESH_RATE = 60000;
 
    public void setContainer(Container container)
    {
       this.container = (EntityContainer)container;
    }
 
    public void init()
    throws Exception
    {
       commitOption = container.getBeanMetaData().getContainerConfiguration().getCommitOption();
 
       if(commitOption == ConfigurationMetaData.D_COMMIT_OPTION)
       {
           //Start Timer Task Now!
           new Timer().schedule(new ForceSynchronization(),0,REFRESH_RATE);
        }
    }
 
    public Container getContainer()
    {
       return container;
    }
 
    private void register(EntityEnterpriseContext ctx, Transaction tx)
    {
    }
 
    private void deregister(EntityEnterpriseContext ctx)
    {
    }
 
    // Interceptor implementation --------------------------------------
 
    public Object invokeHome(MethodInvocation mi)
    throws Exception
    {
       try {
         return getNext().invokeHome(mi);
       } finally {
         // Anonymous was sent in, so if it has an id it was created
         EntityEnterpriseContext ctx = (EntityEnterpriseContext)mi.getEnterpriseContext();
         if (ctx.getId() != null) {
          Transaction tx = mi.getTransaction();
 
          if (tx != null && tx.getStatus() == Status.STATUS_ACTIVE)
              register(ctx, tx); // Set tx
 
          // Currently synched with underlying storage
          ctx.setValid(true);
         }
       }
    }
 
    public Object invoke(MethodInvocation mi)
    throws Exception
    {
       if(commitOption == ConfigurationMetaData.D_COMMIT_OPTION)
       {
           EntityEnterpriseContext ctx = (EntityEnterpriseContext)mi.getEnterpriseContext();
 

           if(ctx.getId()!=null)
           {
               synchronized(ctxToInvalidate)
               {
                 this.ctxToInvalidate.add(ctx);
               }
           }
           else
           {
               synchronized(ctxToInvalidate)
               {
                 this.ctxToInvalidate.remove(ctx);
               }
            }
       }
 
       return getNext().invoke(mi);
    }
 

    private class ForceSynchronization
    extends TimerTask
    {
       ForceSynchronization()
       {
       }
 
        public void run()
        {
           synchronized(ctxToInvalidate)
           {
                Iterator it = ctxToInvalidate.iterator();
 
                while(it.hasNext())
                {
                   EntityEnterpriseContext ctx = (EntityEnterpriseContext)it.next();
                   ctx.setValid(false);
                }
            }
        }
    }
}
 
 

Reply via email to