Package org.infinispan.interceptors.base

Source Code of org.infinispan.interceptors.base.BaseRpcInterceptor

/*
* JBoss, Home of Professional Open Source.
* Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.infinispan.interceptors.base;

import org.infinispan.commands.CommandsFactory;
import org.infinispan.commands.ReplicableCommand;
import org.infinispan.commands.remote.CacheRpcCommand;
import org.infinispan.commands.remote.SingleRpcCommand;
import org.infinispan.context.InvocationContext;
import org.infinispan.context.TransactionContext;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.Start;
import org.infinispan.invocation.Flag;
import org.infinispan.remoting.ReplicationQueue;
import org.infinispan.remoting.ResponseMode;
import org.infinispan.remoting.RpcManager;
import org.infinispan.remoting.transport.Address;
import org.infinispan.transaction.GlobalTransaction;
import org.infinispan.transaction.TransactionTable;

import javax.transaction.Transaction;
import java.util.List;

/**
* Acts as a base for all RPC calls - subclassed by
*
* @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a>
* @since 4.0
*/
public abstract class BaseRpcInterceptor extends CommandInterceptor {
   private ReplicationQueue replicationQueue;
   protected TransactionTable txTable;
   private CommandsFactory commandsFactory;

   protected RpcManager rpcManager;
   protected boolean defaultSynchronous;
   private boolean stateTransferEnabled;

   @Inject
   public void injectComponents(RpcManager rpcManager, ReplicationQueue replicationQueue,
                                TransactionTable txTable, CommandsFactory commandsFactory) {
      this.rpcManager = rpcManager;
      this.replicationQueue = replicationQueue;
      this.txTable = txTable;
      this.commandsFactory = commandsFactory;
   }

   @Start
   public void init() {
      defaultSynchronous = configuration.getCacheMode().isSynchronous();
      stateTransferEnabled = configuration.isFetchInMemoryState();
   }

   /**
    * Checks whether any of the responses are exceptions. If yes, re-throws them (as exceptions or runtime exceptions).
    */
   protected void checkResponses(List rsps) throws Throwable {
      if (rsps != null) {
         for (Object rsp : rsps) {
            if (rsp != null && rsp instanceof Throwable) {
               // lets print a stack trace first.
               if (log.isDebugEnabled())
                  log.debug("Received Throwable from remote cache", (Throwable) rsp);
               throw (Throwable) rsp;
            }
         }
      }
   }

   protected void replicateCall(InvocationContext ctx, CacheRpcCommand call, boolean sync, boolean useOutOfBandMessage) throws Throwable {
      replicateCall(ctx, null, call, sync, useOutOfBandMessage);
   }

   protected void replicateCall(InvocationContext ctx, ReplicableCommand call, boolean sync, boolean useOutOfBandMessage) throws Throwable {
      replicateCall(ctx, null, call, sync, useOutOfBandMessage);
   }

   protected void replicateCall(InvocationContext ctx, CacheRpcCommand call, boolean sync) throws Throwable {
      replicateCall(ctx, null, call, sync, false);
   }

   protected void replicateCall(InvocationContext ctx, ReplicableCommand call, boolean sync) throws Throwable {
      replicateCall(ctx, null, call, sync, false);
   }

   protected void replicateCall(InvocationContext ctx, List<Address> recipients, ReplicableCommand c, boolean sync, boolean useOutOfBandMessage) throws Throwable {
      long syncReplTimeout = configuration.getSyncReplTimeout();

      if (ctx.hasFlag(Flag.FORCE_ASYNCHRONOUS)) sync = false;
      else if (ctx.hasFlag(Flag.FORCE_SYNCHRONOUS)) sync = true;

      // tx-level overrides are more important
      Transaction tx = ctx.getTransaction();
      if (tx != null) {
         TransactionContext transactionContext = ctx.getTransactionContext();
         if (transactionContext != null) {
            if (transactionContext.isForceAsyncReplication()) sync = false;
            else if (transactionContext.isForceSyncReplication()) sync = true;
         }
      }

      replicateCall(recipients, c, sync, useOutOfBandMessage, syncReplTimeout);
   }

   protected void replicateCall(List<Address> recipients, ReplicableCommand call, boolean sync, boolean useOutOfBandMessage, long timeout) throws Throwable {
      if (trace) log.trace("Broadcasting call " + call + " to recipient list " + recipients);

      if (!sync && replicationQueue != null) {
         if (log.isDebugEnabled()) log.debug("Putting call " + call + " on the replication queue.");
         replicationQueue.add(call);
      } else {
         List<Address> callRecipients = recipients;
         if (callRecipients == null) {
            callRecipients = null;
            if (trace)
               log.trace("Setting call recipients to " + callRecipients + " since the original list of recipients passed in is null.");
         }
         SingleRpcCommand command = commandsFactory.buildSingleRpcCommand(call);

         List rsps = rpcManager.invokeRemotely(callRecipients,
                                               command,
                                               sync ? ResponseMode.SYNCHRONOUS : ResponseMode.ASYNCHRONOUS, // is synchronised?
                                               timeout, useOutOfBandMessage, stateTransferEnabled
         );
         if (trace) log.trace("responses=" + rsps);
         if (sync) checkResponses(rsps);
      }
   }

   /**
    * It does not make sense replicating a transaction method(commit, rollback, prepare) if one of the following is
    * true:
    * <pre>
    *    - call was not initiated here, but on other member of the cluster
    *    - there is no transaction. Why broadcast a commit or rollback if there is no transaction going on?
    *    - the current transaction did not modify any data
    * </pre>
    */
   protected final boolean skipReplicationOfTransactionMethod(InvocationContext ctx) {
      GlobalTransaction gtx = ctx.getGlobalTransaction();
      return ctx.getTransaction() == null || gtx == null || gtx.isRemote() || ctx.hasFlag(Flag.CACHE_MODE_LOCAL)
            || !ctx.getTransactionContext().hasModifications();
   }

   /**
    * The call runs in a transaction and it was initiated on this cache instance of the cluster.
    */
   protected final boolean isTransactionalAndLocal(InvocationContext ctx) {
      GlobalTransaction gtx = ctx.getGlobalTransaction();
      boolean isInitiatedHere = gtx != null && !gtx.isRemote();
      return isInitiatedHere && (ctx.getTransaction() != null);
   }

   protected final boolean isSynchronous(InvocationContext ctx) {
      if (ctx.hasFlag(Flag.FORCE_SYNCHRONOUS))
         return true;
      else if (ctx.hasFlag(Flag.FORCE_ASYNCHRONOUS))
         return false;

      return defaultSynchronous;
   }

   protected final boolean isLocalModeForced(InvocationContext ctx) {
      if (ctx.hasFlag(Flag.CACHE_MODE_LOCAL)) {
         if (log.isDebugEnabled()) log.debug("LOCAL mode forced on invocation.  Suppressing clustered events.");
         return true;
      }
      return false;
   }
}
TOP

Related Classes of org.infinispan.interceptors.base.BaseRpcInterceptor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.