|
Marc,
Have changed the name of the
map!
Also,
standardjboss.xml has a node
<optiond-refresh-rate>30</optiond-refresh-rate>
that is along side the <commit-option>
node.
that specifies the refresh rate in seconds.
If option d is specified then this value is read to set the refresh rate.
If the user forgets to specify this then the minimum for this [i.e. the max
refresh rate] is defaulted to 5 seconds [Do we want to make this higher i.e. 20
seconds or something?]
ConfigurationMetaData has been modified to handle
the new option as under
public static final byte D_COMMIT_OPTION =
3;
public static final String[] commitOptionStrings = { "A", "B", "C","D" }; Also it has a new method to return the refresh
rate read from the xml as
//Option D Refresh Rate
optiondrefreshrate = getElementContent(getOptionalChild(element, "optiond-refresh-rate"),optiondrefreshrate); public long
getOptionDRefreshRate() { return
Long.parseLong((optiondrefreshrate!=null)?optiondrefreshrate:"0")*1000;
}
And finally the modified class is as follows. Am
not sure whether it should still be called SoftBallInterceptor though! Also, if
'optiond-refresh-rate' sounds odd we might want to change that!
And yes, I am looking forward to getting the
t-shirt in 2 weeks time when you come down to CPW!
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.HashSet; 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; import org.jboss.util.TimerQueue; import org.jboss.util.TimerTask; 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 validContexts = new HashSet(); /** * The minimum cache refresh rate. If its anything below 5 seconds default to * minimum */ private static long MINIMUM_REFRESH_RATE = 5000; /**
* Standard method implementation */ public void setContainer(Container container) { this.container = (EntityContainer)container; } /**
* Standard method implementation */ public Container getContainer() { return container; } /**
* Initializer */ public void init() throws Exception { //Get Commit option from the jboss/standardjboss xml config file commitOption = container.getBeanMetaData().getContainerConfiguration().getCommitOption(); if(commitOption ==
ConfigurationMetaData.D_COMMIT_OPTION)
{ long refreshRate = container.getBeanMetaData().getContainerConfiguration().getOptionDRefreshRate(); //Sanity Check refreshRate = (refreshRate<MINIMUM_REFRESH_RATE)?MINIMUM_REFRESH_RATE:refreshRate; //Start Timer
Task Now!
new SoftBallScheduler().schedule(new SoftBallSynchronizer(refreshRate)); } } // Interceptor implementation -------------------------------------- public Object invokeHome(MethodInvocation
mi)
throws Exception { //Simply pass on to the next interceptor 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(validContexts) { //Check if already present? if(!this.validContexts.contains(ctx.getCacheKey())) { //If not invalidate cache ctx.setValid(false); //and add to the set to make sure it is skipped next time this.validContexts.add(ctx.getCacheKey()); } } } //Pass on to the next
interceptor
return getNext().invoke(mi); } /**
* The implementation for the TimerQueue that will actually run the * timed task for us. */ private static final class SoftBallScheduler { private static final TimerQueue m_SoftBallScheduler = new TimerQueue(); static { m_SoftBallScheduler.start(); } public final void schedule(TimerTask t) { schedule(t, 0); } public final void schedule(TimerTask t, long delay) { m_SoftBallScheduler.schedule(t, delay); } } /**
* The TimerTask that will reset the hashset and cause the entity to be * invalidated next time round. */ private final class SoftBallSynchronizer extends TimerTask { SoftBallSynchronizer(long refreshRate) { super(refreshRate); } public void
execute()
{ synchronized(validContexts) { //Clear the set. Will force invalidation next time on. validContexts.clear(); } } } } |
