|
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); } } } } } |
- RE: [JBoss-dev] Option D - Take One! K.V. Vinay Menon
- RE: [JBoss-dev] Option D - Take One! marc fleury
