Marc,
    Here goes the next version per your instructions! Note that I have to
synchronize for adding the key to the set. Please let me know if this looks
like what you had in mind. And hey, I have removed the stuff from
invokeHome. It will simply chain it to the next interceptor [the sync
interceptor] now.

Regards,

Vinay

PS: The training was very good.... and I believe anyone seriously
considering J2EE development will benefit from it......

/*
* 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
{
    /**
     * Commit Option from standardjboss.xml or jboss.xml
     */
    protected int commitOption;

    /**
     * The container of this interceptor.
     */
    protected EntityContainer container;

    /**
     * Collection of context cache keys
     */
    protected HashSet ctxToInvalidate = new HashSet();

    /**
     *  The cache refresh rate
     */
    private static int REFRESH_RATE = 30000;


    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
    {
         return getNext().invokeHome(mi);

    }

    public Object invoke(MethodInvocation mi)
    throws Exception
    {
       if(commitOption == ConfigurationMetaData.D_COMMIT_OPTION)
       {
           EntityEnterpriseContext ctx =
(EntityEnterpriseContext)mi.getEnterpriseContext();

           //In case the invalidator thread wakes up!
           synchronized(ctxToInvalidate)
           {
             //Check if already present?
             if(!this.ctxToInvalidate.contains(ctx.getCacheKey()))
             {
                 //If not invalidate cache
                 ctx.setValid(false);
                 //and add to the set to make sure it is skipped next time
                 this.ctxToInvalidate.add(ctx.getCacheKey());
             }
           }
       }

       return getNext().invoke(mi);
    }


    private class ForceSynchronization
    extends TimerTask
    {
       ForceSynchronization()
       {
       }

        public void run()
        {
           synchronized(ctxToInvalidate)
           {
             //Clear the set. Will force invalidation next time on.
             ctxToInvalidate.clear();
           }
        }
    }
}




----- Original Message -----
From: "marc fleury" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Friday, May 11, 2001 7:58 PM
Subject: RE: [JBoss-dev] RE: Option D - Take One !


> |Marc,
> |
> |Will do over the weekend! Just had time today to give this a try! [and
that
> |too about 45 mins!]. But I'll see to it that I go thru the material and
do
> |it the way you'd like to see it work!!
>
> Great... btw I forgot to welcome you and congratulate you for taking the
> courageous plunge of hacking the container interceptors for your first
> server contribution.. that is definitely ballsy.  I realize the class
wasn't
> lost at all since you have a firm grasp of the graph of flows, the plugins
> the JMX init and the invoke detyped mechanisms (you took the right
decision
> for the interceptor).
>
> <PLUG> The training can turn all of you in container developers </PLUG>.
So
> you go and get that algo right and lightweight and we put it in.
>
> regards
>
> marc
>
> PS: PLEASE READ THE CLASS EXCERCISE AND MY PREVIOUS MAIL :)
>
> |
> |Cheers,
> |
> |Vinay
> |
> |Just took a loo
> |----- Original Message -----
> |From: "marc fleury" <[EMAIL PROTECTED]>
> |To: <[EMAIL PROTECTED]>
> |Sent: Friday, May 11, 2001 7:12 PM
> |Subject: RE: [JBoss-dev] RE: Option D - Take One !
> |
> |
> |> Vinay,
> |>
> |> // The valid variables, make it a hashset
> |> Map validContext;
> |>
> |> invoke(MI mi) {
> |>
> |> try {
> |> // Use the cache key, it is safe
> |> if (!validContext.contains(((EntityEnterpriseContext)
> |> mi.getEnterpriseContext()).key) {
> |>
> |> //The context is not in the map, it will be loaded in the next
> |interceptor
> |> ctx.setValid(false);
> |>
> |> synchronized (validContext)
> |> // Add it to the map so that it is seen the next time
> |> validContext.add(... mi.getEnterpriseContext().key...);
> |> }
> |>
> |> invokeNext(mi);
> |>    }
> |> finally {
> |>
> |> ctx.setValid(true);
> |> }
> |>
> |> // The thread that does the work should only do the following
> |> synchronized (validContext)
> |> validContext.clear();
> |>
> |> The way this work is that when the thread wakes up it removes
> |all the keys
> |> from the valid instances.
> |>
> |> You start there is no one in the valid stuff, if a call comes it gets a
> |map
> |> miss and asks for the instance to be reloaded.  The next time a
> |call comes
> |> the instance is in the map the ctx is still at valid and the next
> |> interceptor won't load the instance.
> |> When the thread wakes up it empties the map so that the threads coming
in
> |> through invoke see that the instance isn't in the validContexts and
asks
> |for
> |> a reload of it.
> |>
> |> I don't believe that the synchronization of the map is really necessary
> |(at
> |> all) and if it is I don't see it as needed other than the place where
> |there
> |> is structural changes.  A "miss" will mean a reload so that treats the
> |state
> |> in a safe way.
> |>
> |> regards
> |>
> |> marc
> |>
> |>
> |> |-----Original Message-----
> |> |From: [EMAIL PROTECTED]
> |> |[mailto:[EMAIL PROTECTED]]On Behalf Of
K.V.
> |> |Vinay Menon
> |> |Sent: Friday, May 11, 2001 11:29 AM
> |> |To: [EMAIL PROTECTED]
> |> |Subject: Re: [JBoss-dev] RE: Option D - Take One !
> |> |
> |> |
> |> |Hi Simon.
> |> |    Thanks for the response. I must admit that I have really
> |not dug deep
> |> |into the guts of quite a few classes in JBoss. Why I put it in
> |a separate
> |> |Interceptor is
> |> |
> |> |1. Does not become part of standard jboss release if we go for spec
> |> |compliance and stuff!
> |> |2. Users can add and remove it as required from the jboss.xml so that
> |they
> |> |have more control over it.
> |> |3. Code does not really touch any other code classes [except for the
> |> |metadata bit]
> |> |
> |> |
> |> |Vinay
> |> |----- Original Message -----
> |> |From: "Bordet, Simone" <[EMAIL PROTECTED]>
> |> |To: "JBoss Development Mailing List (E-mail)"
> |> |<[EMAIL PROTECTED]>
> |> |Sent: Friday, May 11, 2001 4:18 PM
> |> |Subject: [JBoss-dev] RE: Option D - Take One !
> |> |
> |> |
> |> |> Hey Vinay,
> |> |>
> |> |> [please plain text email]
> |> |>
> |> |> > 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.
> |> |>
> |> |> I would have written a simple TimerTask in a LRU cache policy, as
I've
> |> |done
> |> |> for the stateful bean removal.
> |> |> The issues (entity beans invalidation and stateful beans
> |> |removal) are very
> |> |> similar, aren't they ?
> |> |>
> |> |> > 1. There is an invalidation timer task per entity bean [I
> |> |> > persum per-EntityEnterpriseContext maps to per bean and not
> |> |> > per bean instance]
> |> |>
> |> |> I saw you use java.util.TimerTask.
> |> |> I reimplemented them because in the early days we wanted to be
> |compatible
> |> |> with jdk1.2.2, and these classes were added only in JDK 1.3. I don't
> |know
> |> |if
> |> |> this constraint is still there (running the server in a 1.2.2 JVM)
> |but...
> |> |>
> |> |> > 2. The refersh rate is currently set at 60secs but could be
> |> |> > moved elsewhere to the jboss config xml
> |> |>
> |> |> OK
> |> |>
> |> |> > 3. The Configuration Metadat now has an entry for option D.
> |> |>
> |> |> OK
> |> |>
> |> |> > 4. The interceptor does NOT reload the entity. It just
> |> |> > invalidates the cache. The entity reload is managed by the
> |> |> > EntitySynchronizationInterceptor.
> |> |>
> |> |> YES
> |> |>
> |> |> > Does anyone want to go thru this and get back to me?
> |> |>
> |> |> As I've pointed out I would have written it with a
> |> |org.jboss.util.TimerTask
> |> |> in a LRUEntityContextCachePolicy subclass.
> |> |> In there I would have locked the cache, walked all the cached
context
> |and
> |> |> call setValid(false) on them, more or less like in the
> |> |> LRUStatefulContextCachePolicy.
> |> |> What do you think ?
> |> |>
> |> |> Cheers,
> |> |>
> |> |> Simon
> |> |>
> |> |> _______________________________________________
> |> |> Jboss-development mailing list
> |> |> [EMAIL PROTECTED]
> |> |> http://lists.sourceforge.net/lists/listinfo/jboss-development
> |> |
> |> |
> |> |_______________________________________________
> |> |Jboss-development mailing list
> |> |[EMAIL PROTECTED]
> |> |http://lists.sourceforge.net/lists/listinfo/jboss-development
> |>
> |>
> |>
> |> _______________________________________________
> |> Jboss-development mailing list
> |> [EMAIL PROTECTED]
> |> http://lists.sourceforge.net/lists/listinfo/jboss-development
> |
> |
> |_______________________________________________
> |Jboss-development mailing list
> |[EMAIL PROTECTED]
> |http://lists.sourceforge.net/lists/listinfo/jboss-development
>
>
>
> _______________________________________________
> Jboss-development mailing list
> [EMAIL PROTECTED]
> http://lists.sourceforge.net/lists/listinfo/jboss-development


_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to