Search in sources :

Example 1 with TxReadOnlyKeyCommand

use of org.infinispan.commands.functional.TxReadOnlyKeyCommand in project infinispan by infinispan.

the class CallInterceptor method visitReadOnlyKeyCommand.

@Override
public Object visitReadOnlyKeyCommand(InvocationContext ctx, ReadOnlyKeyCommand command) throws Throwable {
    if (command instanceof TxReadOnlyKeyCommand) {
        TxReadOnlyKeyCommand txReadOnlyKeyCommand = (TxReadOnlyKeyCommand) command;
        List<Mutation> mutations = txReadOnlyKeyCommand.getMutations();
        if (mutations != null && !mutations.isEmpty()) {
            return visitTxReadOnlyKeyCommand(ctx, txReadOnlyKeyCommand, mutations);
        }
    }
    Object key = command.getKey();
    CacheEntry entry = ctx.lookupEntry(key);
    if (entry == null) {
        throw new IllegalStateException();
    }
    DataConversion keyDataConversion = command.getKeyDataConversion();
    EntryView.ReadEntryView ro = entry.isNull() ? EntryViews.noValue(key, keyDataConversion) : EntryViews.readOnly(entry, keyDataConversion, command.getValueDataConversion());
    Object ret = snapshot(command.getFunction().apply(ro));
    // We'll consider the entry always read for stats purposes even if the function is a noop
    return Param.StatisticsMode.isSkip(command.getParams()) ? ret : StatsEnvelope.create(ret, entry.isNull());
}
Also used : DataConversion(org.infinispan.encoding.DataConversion) EntryView(org.infinispan.functional.EntryView) TxReadOnlyKeyCommand(org.infinispan.commands.functional.TxReadOnlyKeyCommand) Mutation(org.infinispan.commands.functional.Mutation) InternalCacheEntry(org.infinispan.container.entries.InternalCacheEntry) CacheEntry(org.infinispan.container.entries.CacheEntry)

Example 2 with TxReadOnlyKeyCommand

use of org.infinispan.commands.functional.TxReadOnlyKeyCommand in project infinispan by infinispan.

the class TxDistributionInterceptor method handleTxFunctionalCommand.

public <C extends AbstractDataWriteCommand & FunctionalCommand> Object handleTxFunctionalCommand(InvocationContext ctx, C command) {
    Object key = command.getKey();
    if (ctx.isOriginLocal()) {
        CacheEntry entry = ctx.lookupEntry(key);
        if (entry == null) {
            if (command.hasAnyFlag(SKIP_REMOTE_FLAGS) || command.loadType() == VisitableCommand.LoadType.DONT_LOAD) {
                entryFactory.wrapExternalEntry(ctx, key, null, false, true);
                return invokeNext(ctx, command);
            }
            LocalizedCacheTopology cacheTopology = checkTopologyId(command);
            int segment = command.getSegment();
            DistributionInfo distributionInfo = cacheTopology.getSegmentDistribution(segment);
            // we could have stale value after state transfer.
            if (distributionInfo.isWriteOwner() || forceRemoteReadForFunctionalCommands && !command.hasAnyFlag(FlagBitSets.SKIP_XSITE_BACKUP)) {
                return asyncInvokeNext(ctx, command, remoteGetSingleKey(ctx, command, key, true));
            }
            List<Mutation<Object, Object, ?>> mutationsOnKey = getMutationsOnKey((TxInvocationContext) ctx, command, key);
            mutationsOnKey.add(command.toMutation(key));
            TxReadOnlyKeyCommand remoteRead = commandsFactory.buildTxReadOnlyKeyCommand(key, null, mutationsOnKey, segment, command.getParams(), command.getKeyDataConversion(), command.getValueDataConversion());
            remoteRead.setTopologyId(command.getTopologyId());
            CompletionStage<SuccessfulResponse> remoteGet = rpcManager.invokeCommandStaggered(distributionInfo.readOwners(), remoteRead, new RemoteGetSingleKeyCollector(), rpcManager.getSyncRpcOptions());
            return asyncValue(remoteGet).thenApply(ctx, command, (rCtx, rCommand, response) -> {
                Object responseValue = ((SuccessfulResponse) response).getResponseValue();
                return unwrapFunctionalResultOnOrigin(rCtx, rCommand.getKey(), responseValue);
            });
        }
        // It's possible that this is not an owner, but the entry was loaded from L1 - let the command run
        return invokeNext(ctx, command);
    } else {
        if (!checkTopologyId(command).isWriteOwner(key)) {
            return null;
        }
        CacheEntry entry = ctx.lookupEntry(key);
        if (entry == null) {
            if (command.hasAnyFlag(SKIP_REMOTE_FLAGS) || command.loadType() == VisitableCommand.LoadType.DONT_LOAD) {
                // in transactional mode, we always need the entry wrapped
                entryFactory.wrapExternalEntry(ctx, key, null, false, true);
            } else {
                return asyncInvokeNext(ctx, command, remoteGetSingleKey(ctx, command, command.getKey(), true));
            }
        }
        return invokeNextThenApply(ctx, command, (rCtx, rCommand, rv) -> wrapFunctionalResultOnNonOriginOnReturn(rv, entry));
    }
}
Also used : SuccessfulResponse(org.infinispan.remoting.responses.SuccessfulResponse) TxReadOnlyKeyCommand(org.infinispan.commands.functional.TxReadOnlyKeyCommand) LocalizedCacheTopology(org.infinispan.distribution.LocalizedCacheTopology) Mutation(org.infinispan.commands.functional.Mutation) CacheEntry(org.infinispan.container.entries.CacheEntry) DistributionInfo(org.infinispan.distribution.DistributionInfo)

Aggregations

Mutation (org.infinispan.commands.functional.Mutation)2 TxReadOnlyKeyCommand (org.infinispan.commands.functional.TxReadOnlyKeyCommand)2 CacheEntry (org.infinispan.container.entries.CacheEntry)2 InternalCacheEntry (org.infinispan.container.entries.InternalCacheEntry)1 DistributionInfo (org.infinispan.distribution.DistributionInfo)1 LocalizedCacheTopology (org.infinispan.distribution.LocalizedCacheTopology)1 DataConversion (org.infinispan.encoding.DataConversion)1 EntryView (org.infinispan.functional.EntryView)1 SuccessfulResponse (org.infinispan.remoting.responses.SuccessfulResponse)1