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());
}
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));
}
}
Aggregations