Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.infinispan.interceptors.distribution;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import org.infinispan.commands.FlagAffectedCommand;
import org.infinispan.commands.ReplicableCommand;
import org.infinispan.commands.TopologyAffectedCommand;
import org.infinispan.commands.VisitableCommand;
import org.infinispan.commands.control.LockControlCommand;
import org.infinispan.commands.functional.FunctionalCommand;
import org.infinispan.commands.functional.Mutation;
import org.infinispan.commands.functional.ReadOnlyKeyCommand;
import org.infinispan.commands.functional.ReadOnlyManyCommand;
import org.infinispan.commands.functional.ReadWriteKeyCommand;
import org.infinispan.commands.functional.ReadWriteKeyValueCommand;
import org.infinispan.commands.functional.ReadWriteManyCommand;
import org.infinispan.commands.functional.ReadWriteManyEntriesCommand;
import org.infinispan.commands.functional.TxReadOnlyKeyCommand;
import org.infinispan.commands.functional.TxReadOnlyManyCommand;
import org.infinispan.commands.functional.WriteOnlyKeyCommand;
import org.infinispan.commands.functional.WriteOnlyKeyValueCommand;
import org.infinispan.commands.functional.WriteOnlyManyCommand;
import org.infinispan.commands.functional.WriteOnlyManyEntriesCommand;
import org.infinispan.commands.tx.CommitCommand;
import org.infinispan.commands.tx.PrepareCommand;
import org.infinispan.commands.tx.RollbackCommand;
import org.infinispan.commands.tx.TransactionBoundaryCommand;
import org.infinispan.commands.tx.VersionedCommitCommand;
import org.infinispan.commands.write.AbstractDataWriteCommand;
import org.infinispan.commands.write.ComputeCommand;
import org.infinispan.commands.write.ComputeIfAbsentCommand;
import org.infinispan.commands.write.PutKeyValueCommand;
import org.infinispan.commands.write.PutMapCommand;
import org.infinispan.commands.write.RemoveCommand;
import org.infinispan.commands.write.ReplaceCommand;
import org.infinispan.commands.write.ValueMatcher;
import org.infinispan.commands.write.WriteCommand;
import org.infinispan.functional.EntryView;
import org.infinispan.container.entries.CacheEntry;
import org.infinispan.container.entries.MVCCEntry;
import org.infinispan.container.versioning.EntryVersionsMap;
import org.infinispan.context.InvocationContext;
import org.infinispan.context.impl.FlagBitSets;
import org.infinispan.context.impl.LocalTxInvocationContext;
import org.infinispan.context.impl.TxInvocationContext;
import org.infinispan.distribution.LocalizedCacheTopology;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.functional.impl.EntryViews;
import org.infinispan.partitionhandling.impl.PartitionHandlingManager;
import org.infinispan.remoting.inboundhandler.DeliverOrder;
import org.infinispan.remoting.responses.CacheNotFoundResponse;
import org.infinispan.remoting.responses.Response;
import org.infinispan.remoting.responses.SuccessfulResponse;
import org.infinispan.remoting.responses.UnsureResponse;
import org.infinispan.remoting.rpc.ResponseMode;
import org.infinispan.remoting.rpc.RpcOptions;
import org.infinispan.remoting.transport.Address;
import org.infinispan.statetransfer.AllOwnersLostException;
import org.infinispan.statetransfer.OutdatedTopologyException;
import org.infinispan.transaction.impl.LocalTransaction;
import org.infinispan.transaction.xa.GlobalTransaction;
import org.infinispan.util.concurrent.CompletableFutures;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
/**
* Handles the distribution of the transactional caches.
*
* @author Mircea Markus
* @author Dan Berindei
*/
public class TxDistributionInterceptor extends BaseDistributionInterceptor {
private static final Log log = LogFactory.getLog(TxDistributionInterceptor.class);
private static final boolean trace = log.isTraceEnabled();
private static final long SKIP_REMOTE_FLAGS = FlagBitSets.CACHE_MODE_LOCAL | FlagBitSets.SKIP_REMOTE_LOOKUP;
private PartitionHandlingManager partitionHandlingManager;
private boolean forceRemoteReadForFunctionalCommands;
private final TxReadOnlyManyHelper txReadOnlyManyHelper = new TxReadOnlyManyHelper();
private final ReadWriteManyHelper readWriteManyHelper = new ReadWriteManyHelper();
private final ReadWriteManyEntriesHelper readWriteManyEntriesHelper = new ReadWriteManyEntriesHelper();
@Inject
public void inject(PartitionHandlingManager partitionHandlingManager) {
this.partitionHandlingManager = partitionHandlingManager;
}
@Override
public void configure() {
super.configure();
// When cross-site replication is enabled, we need to retrieve the previous value from remote node
// even for functional commands; we will need to send the modified value to backup sites and therefore
// we need it in the context.
forceRemoteReadForFunctionalCommands = cacheConfiguration.sites().hasEnabledBackups();
}
@Override
public Object visitReplaceCommand(InvocationContext ctx, ReplaceCommand command) throws Throwable {
return handleTxWriteCommand(ctx, command, command.getKey());
}
@Override
public Object visitComputeCommand(InvocationContext ctx, ComputeCommand command) throws Throwable {
// Contrary to functional commands, compute() needs to return the new value returned by the remapping function.
// Since we can assume that old and new values are comparable in size, fetching old value into context is acceptable
// and it is more efficient in case that we execute more subsequent modifications than sending the return value.
return handleTxWriteCommand(ctx, command, command.getKey());
}
@Override
public Object visitComputeIfAbsentCommand(InvocationContext ctx, ComputeIfAbsentCommand command) throws Throwable {
// Contrary to functional commands, compute() needs to return the new value returned by the remapping function.
// Since we can assume that old and new values are comparable in size, fetching old value into context is acceptable
// and it is more efficient in case that we execute more subsequent modifications than sending the return value.
return handleTxWriteCommand(ctx, command, command.getKey());
}
private void updateMatcherForRetry(WriteCommand command) {
// The command is already included in PrepareCommand.modifications - when the command is executed on the remote
// owners it should not behave conditionally anymore because its success/failure is defined on originator.
command.setValueMatcher(command.isSuccessful() ? ValueMatcher.MATCH_ALWAYS : ValueMatcher.MATCH_NEVER);
}
@Override
public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
return handleTxWriteCommand(ctx, command, command.getKey());
}
@Override
public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
if (command.hasAnyFlag(FlagBitSets.PUT_FOR_EXTERNAL_READ)) {
return handleNonTxWriteCommand(ctx, command);
}
return handleTxWriteCommand(ctx, command, command.getKey());
}
@Override
public Object visitPutMapCommand(InvocationContext ctx, PutMapCommand command) throws Throwable {
return handleTxWriteManyEntriesCommand(ctx, command, command.getMap(),
(c, entries) -> new PutMapCommand(c).withMap(entries));
}
@Override
public Object visitLockControlCommand(TxInvocationContext ctx, LockControlCommand command)
throws Throwable {
if (ctx.isOriginLocal()) {
TxInvocationContext localTxCtx = (TxInvocationContext) ctx;
Collection affectedNodes = checkTopologyId(command).getWriteOwners(command.getKeys());
Collection recipients = isReplicated ? null : affectedNodes;
localTxCtx.getCacheTransaction().locksAcquired(affectedNodes);
log.tracef("Registered remote locks acquired %s", affectedNodes);
RpcOptions rpcOptions = rpcManager.getRpcOptionsBuilder(ResponseMode.SYNCHRONOUS_IGNORE_LEAVERS,
DeliverOrder.NONE).build();
CompletableFuture