Package org.infinispan.interceptors

Source Code of org.infinispan.interceptors.DistTxInterceptor$ReplayCommandVisitor

/*
* JBoss, Home of Professional Open Source
* Copyright 2009 Red Hat Inc. and/or its affiliates and other
* contributors as indicated by the @author tags. All rights reserved.
* See the copyright.txt 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;

import org.infinispan.commands.AbstractVisitor;
import org.infinispan.commands.CommandsFactory;
import org.infinispan.commands.VisitableCommand;
import org.infinispan.commands.control.LockControlCommand;
import org.infinispan.commands.tx.CommitCommand;
import org.infinispan.commands.tx.PrepareCommand;
import org.infinispan.commands.tx.RollbackCommand;
import org.infinispan.commands.write.*;
import org.infinispan.context.InvocationContext;
import org.infinispan.context.impl.TxInvocationContext;
import org.infinispan.distribution.DistributionManager;
import org.infinispan.distribution.RehashInProgressException;
import org.infinispan.factories.annotations.Inject;

import java.util.HashMap;
import java.util.Map;

/**
* A special form of the TxInterceptor that is aware of distribution and consistent hashing, and as such only replays
* methods during a remote prepare that are targeted to this specific cache instance.
*
* @author Manik Surtani
* @since 4.0
*/
public class DistTxInterceptor extends TxInterceptor {

   DistributionManager dm;
   ReplayCommandVisitor replayCommandVisitor = new ReplayCommandVisitor();
   private CommandsFactory commandsFactory;

   @Inject
   public void injectDistributionManager(DistributionManager dm, CommandsFactory commandsFactory) {
      this.dm = dm;
      this.commandsFactory = commandsFactory;
   }

   /**
    * Only replays modifications that are
    */
   @Override
   protected VisitableCommand getCommandToReplay(VisitableCommand command) {
      try {
         return (VisitableCommand) command.acceptVisitor(null, replayCommandVisitor);
      } catch (RuntimeException re) {
         throw re;
      } catch (Throwable th) {
         throw new RuntimeException(th);
      }
   }

   @Override
   public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand cmd) throws Throwable {
      if (!dm.getTransactionLogger().beforeCommand(ctx, cmd)) {
         throw new RehashInProgressException("Timed out waiting for the transaction lock");
      }
      try {
         return super.visitPrepareCommand(ctx, cmd);
      } finally {
         dm.getTransactionLogger().afterCommand(ctx, cmd);
      }
   }

   @Override
   public Object visitRollbackCommand(TxInvocationContext ctx, RollbackCommand cmd) throws Throwable {
      if (!dm.getTransactionLogger().beforeCommand(ctx, cmd)) {
         throw new RehashInProgressException("Timed out waiting for the transaction lock");
      }
      try {
         return super.visitRollbackCommand(ctx, cmd);
      } finally {
         dm.getTransactionLogger().afterCommand(ctx, cmd);
      }
   }

   @Override
   public Object visitCommitCommand(TxInvocationContext ctx, CommitCommand cmd) throws Throwable {
      if (!dm.getTransactionLogger().beforeCommand(ctx, cmd)) {
         throw new RehashInProgressException("Timed out waiting for the transaction lock");
      }
      try {
         return super.visitCommitCommand(ctx, cmd);
      } finally {
         dm.getTransactionLogger().afterCommand(ctx, cmd);
      }
   }

   @Override
   public Object visitLockControlCommand(TxInvocationContext ctx, LockControlCommand cmd) throws Throwable {
      if (!dm.getTransactionLogger().beforeCommand(ctx, cmd)) {
         throw new RehashInProgressException("Timed out waiting for the transaction lock");
      }
      try {
         return super.visitLockControlCommand(ctx, cmd);
      } finally {
         dm.getTransactionLogger().afterCommand(ctx, cmd);
      }
   }

   @Override
   public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
      if (!dm.getTransactionLogger().beforeCommand(ctx, command)) {
         throw new RehashInProgressException("Timed out waiting for the transaction lock");
      }
      try {
         return super.visitPutKeyValueCommand(ctx, command);
      } finally {
         dm.getTransactionLogger().afterCommand(ctx, command);
      }
   }

   @Override
   public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
      if (!dm.getTransactionLogger().beforeCommand(ctx, command)) {
         throw new RehashInProgressException("Timed out waiting for the transaction lock");
      }
      try {
         return super.visitRemoveCommand(ctx, command);
      } finally {
         dm.getTransactionLogger().afterCommand(ctx, command);
      }
   }

   @Override
   public Object visitReplaceCommand(InvocationContext ctx, ReplaceCommand command) throws Throwable {
      if (!dm.getTransactionLogger().beforeCommand(ctx, command)) {
         throw new RehashInProgressException("Timed out waiting for the transaction lock");
      }
      try {
         return super.visitReplaceCommand(ctx, command);
      } finally {
         dm.getTransactionLogger().afterCommand(ctx, command);
      }
   }

   @Override
   public Object visitClearCommand(InvocationContext ctx, ClearCommand command) throws Throwable {
      if (!dm.getTransactionLogger().beforeCommand(ctx, command)) {
         throw new RehashInProgressException("Timed out waiting for the transaction lock");
      }
      try {
         return super.visitClearCommand(ctx, command);
      } finally {
         dm.getTransactionLogger().afterCommand(ctx, command);
      }
   }

   @Override
   public Object visitPutMapCommand(InvocationContext ctx, PutMapCommand command) throws Throwable {
      if (!dm.getTransactionLogger().beforeCommand(ctx, command)) {
         throw new RehashInProgressException("Timed out waiting for the transaction lock");
      }
      try {
         return super.visitPutMapCommand(ctx, command);
      } finally {
         dm.getTransactionLogger().afterCommand(ctx, command);
      }
   }


   class ReplayCommandVisitor extends AbstractVisitor {
      @Override
      public Object visitPutMapCommand(InvocationContext ctx, PutMapCommand command) {
         Map newMap = new HashMap();
         for (Map.Entry entry : command.getMap().entrySet()) {
            if (dm.getLocality(entry.getKey()).isLocal()) newMap.put(entry.getKey(), entry.getValue());
         }

         if (newMap.isEmpty()) return null;
         if (newMap.size() == command.getMap().size()) return command;
         return commandsFactory.buildPutMapCommand(newMap, command.getLifespanMillis(), command.getMaxIdleTimeMillis(), ctx.getFlags());
      }

      @Override
      public Object visitPutKeyValueCommand(InvocationContext ignored, PutKeyValueCommand command) {
         return visitDataWriteCommand(command);
      }

      @Override
      public Object visitRemoveCommand(InvocationContext ignored, RemoveCommand command) {
         return visitDataWriteCommand(command);
      }

      @Override
      public Object visitReplaceCommand(InvocationContext ignored, ReplaceCommand command) {
         return visitDataWriteCommand(command);
      }

      private VisitableCommand visitDataWriteCommand(DataWriteCommand command) {
         return dm.getLocality(command.getKey()).isLocal() ? command : null;
      }

      @Override
      public Object handleDefault(InvocationContext ignored, VisitableCommand command) {
         return command;
      }
   }
}
TOP

Related Classes of org.infinispan.interceptors.DistTxInterceptor$ReplayCommandVisitor

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.