Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 145   Methods: 3
NCLOC: 92   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ReplicationInterceptor.java 82.4% 85.4% 100% 84.7%
coverage coverage
 1    package org.jboss.cache.interceptors;
 2   
 3    import org.jboss.cache.InvocationContext;
 4    import org.jboss.cache.config.Configuration;
 5    import org.jboss.cache.config.Option;
 6    import org.jboss.cache.marshall.MethodCall;
 7    import org.jboss.cache.marshall.MethodDeclarations;
 8    import org.jboss.cache.transaction.GlobalTransaction;
 9   
 10    /**
 11    * Takes care of replicating modifications to other nodes in a cluster. Also
 12    * listens for prepare(), commit() and rollback() messages which are received
 13    * 'side-ways' (see docs/design/Refactoring.txt).
 14    *
 15    * @author Bela Ban
 16    * @version $Id: ReplicationInterceptor.java,v 1.44 2007/05/23 15:22:03 msurtani Exp $
 17    */
 18    public class ReplicationInterceptor extends BaseRpcInterceptor
 19    {
 20   
 21  311664 public Object invoke(InvocationContext ctx) throws Throwable
 22    {
 23  311664 MethodCall m = ctx.getMethodCall();
 24  311664 GlobalTransaction gtx = ctx.getGlobalTransaction();
 25   
 26    // bypass for buddy group org metod calls.
 27  731 if (MethodDeclarations.isBuddyGroupOrganisationMethod(m.getMethodId())) return super.invoke(ctx);
 28   
 29  310933 boolean isLocalCommitOrRollback = gtx != null && !gtx.isRemote() && (m.getMethodId() == MethodDeclarations.commitMethod_id || m.getMethodId() == MethodDeclarations.rollbackMethod_id);
 30   
 31  0 if (log.isTraceEnabled()) log.trace("isLocalCommitOrRollback? " + isLocalCommitOrRollback + "; gtx = " + gtx);
 32   
 33    // pass up the chain if not a local commit or rollback (in which case replicate first)
 34  310933 Object o = isLocalCommitOrRollback ? null : super.invoke(ctx);
 35    // ctx = cache.getInvocationContext();
 36   
 37  310901 Option optionOverride = ctx.getOptionOverrides();
 38   
 39  310901 if (optionOverride != null && optionOverride.isCacheModeLocal() && ctx.getTransaction() == null)
 40    {
 41  275 log.trace("skip replication");
 42  275 return isLocalCommitOrRollback ? super.invoke(ctx) : o;
 43    }
 44   
 45    // could be potentially TRANSACTIONAL. If so, we register for transaction completion callbacks (if we
 46    // have not yet done so
 47  310626 if (ctx.getTransaction() != null)
 48    {
 49  61852 if (gtx != null && !gtx.isRemote())
 50    {
 51    // lets see what sort of method we've got.
 52  56276 switch (m.getMethodId())
 53    {
 54  10590 case MethodDeclarations.commitMethod_id:
 55    // REPL_ASYNC will result in only a prepare() method - 1 phase commit.
 56  10577 if (containsModifications(ctx)) replicateCall(m, configuration.isSyncCommitPhase());
 57    // now pass up the chain
 58  10588 o = super.invoke(ctx);
 59  10587 break;
 60  10645 case MethodDeclarations.prepareMethod_id:
 61  10645 if (containsModifications(ctx))
 62    {
 63    // this is a prepare method
 64  10639 runPreparePhase(m, gtx);
 65    }
 66  10621 break;
 67  55 case MethodDeclarations.rollbackMethod_id:
 68    // REPL_ASYNC will result in only a prepare() method - 1 phase commit.
 69  55 if (containsModifications(ctx) && !ctx.isLocalRollbackOnly())
 70    {
 71  24 replicateCall(m, configuration.isSyncRollbackPhase());
 72    }
 73    // now pass up the chain
 74  55 o = super.invoke(ctx);
 75  55 break;
 76  0 case MethodDeclarations.putForExternalReadMethodLocal_id:
 77  0 cache.getTransactionTable().get(gtx).setForceAsyncReplication(true);
 78    }
 79    }
 80    }
 81  248774 else if (MethodDeclarations.isCrudMethod(m.getMethodId()))
 82    {
 83    // NON-TRANSACTIONAL and CRUD method
 84  0 if (log.isTraceEnabled()) log.trace("Non-tx crud meth");
 85  132939 if (ctx.isOriginLocal())
 86    {
 87    // don't re-broadcast if we've received this from anotehr cache in the cluster.
 88  91544 handleReplicatedMethod(m, configuration.getCacheMode());
 89    }
 90    }
 91    else
 92    {
 93  0 if (log.isTraceEnabled()) log.trace("Non-tx and non crud meth");
 94    }
 95   
 96  310589 return o;
 97    }
 98   
 99  91544 void handleReplicatedMethod(MethodCall m, Configuration.CacheMode mode) throws Throwable
 100    {
 101  91544 if (log.isTraceEnabled())
 102    {
 103  0 log.trace("invoking method " + m + ", members=" + cache.getMembers() + ", mode=" +
 104    configuration.getCacheMode() + ", exclude_self=" + true + ", timeout=" +
 105    configuration.getSyncReplTimeout());
 106    }
 107  91544 if (mode == Configuration.CacheMode.REPL_ASYNC || m.getMethodId() == MethodDeclarations.putForExternalReadMethodLocal_id)
 108    {
 109    // 2. Replicate change to all *other* members (exclude self !)
 110  248 replicateCall(m, false);
 111    }
 112    else
 113    {
 114    // REVISIT Needs to exclude itself and apply the local change manually.
 115    // This is needed such that transient field is modified properly in-VM.
 116  91296 replicateCall(m, true);
 117    }
 118    }
 119   
 120    /**
 121    * Calls prepare(GlobalTransaction,List,org.jgroups.Address,boolean)) in all members except self.
 122    * Waits for all responses. If one of the members failed to prepare, its return value
 123    * will be an exception. If there is one exception we rethrow it. This will mark the
 124    * current transaction as rolled back, which will cause the
 125    * afterCompletion(int) callback to have a status
 126    * of <tt>MARKED_ROLLBACK</tt>. When we get that call, we simply roll back the
 127    * transaction.<br/>
 128    * If everything runs okay, the afterCompletion(int)
 129    * callback will trigger the @link #runCommitPhase(GlobalTransaction)).
 130    * <br/>
 131    *
 132    * @throws Exception
 133    */
 134  10639 protected void runPreparePhase(MethodCall prepareMethod, GlobalTransaction gtx) throws Throwable
 135    {
 136  10639 boolean async = configuration.getCacheMode() == Configuration.CacheMode.REPL_ASYNC;
 137  10639 if (log.isTraceEnabled())
 138    {
 139  0 log.trace("(" + cache.getLocalAddress() + "): running remote prepare for global tx " + gtx + " with async mode=" + async);
 140    }
 141   
 142    // this method will return immediately if we're the only member (because exclude_self=true)
 143  10639 replicateCall(prepareMethod, !async);
 144    }
 145    }