use of org.infinispan.remoting.responses.SuccessfulResponse in project infinispan by infinispan.
the class BaseDistributionInterceptor method visitReadOnlyKeyCommand.
@Override
public Object visitReadOnlyKeyCommand(InvocationContext ctx, ReadOnlyKeyCommand command) throws Throwable {
// TODO: repeatable-reads are not implemented, these need to keep the read values on remote side for the duration
// of the transaction, and that requires synchronous invocation of the readonly command on all owners.
// For better consistency, use versioning and write skew check that will fail the transaction when we apply
// the function on different version of the entry than the one previously read
Object key = command.getKey();
CacheEntry entry = ctx.lookupEntry(key);
if (entry != null) {
if (ctx.isOriginLocal()) {
// the entry is owned locally (it is NullCacheEntry if it was not found), no need to go remote
return invokeNext(ctx, command);
} else {
return invokeNextThenApply(ctx, command, (rCtx, rCommand, rv) -> wrapFunctionalResultOnNonOriginOnReturn(rv, entry));
}
}
if (!ctx.isOriginLocal()) {
return UnsureResponse.INSTANCE;
}
if (readNeedsRemoteValue(command)) {
LocalizedCacheTopology cacheTopology = checkTopologyId(command);
Collection<Address> owners = cacheTopology.getDistribution(key).readOwners();
if (log.isTraceEnabled())
log.tracef("Doing a remote get for key %s in topology %d to %s", key, cacheTopology.getTopologyId(), owners);
ReadOnlyKeyCommand remoteCommand = remoteReadOnlyCommand(ctx, command);
// make sure that the command topology is set to the value according which we route it
remoteCommand.setTopologyId(cacheTopology.getTopologyId());
CompletionStage<SuccessfulResponse> rpc = rpcManager.invokeCommandStaggered(owners, remoteCommand, new RemoteGetSingleKeyCollector(), rpcManager.getSyncRpcOptions());
return asyncValue(rpc).thenApply(ctx, command, (rCtx, rCommand, response) -> {
Object responseValue = ((SuccessfulResponse) response).getResponseValue();
return unwrapFunctionalResultOnOrigin(rCtx, rCommand.getKey(), responseValue);
});
} else {
// This has LOCAL flags, just wrap NullCacheEntry and let the command run
entryFactory.wrapExternalEntry(ctx, key, NullCacheEntry.getInstance(), true, false);
return invokeNext(ctx, command);
}
}
use of org.infinispan.remoting.responses.SuccessfulResponse in project infinispan by infinispan.
the class RpcManagerCustomReplicableCommandTest method testInvokeRemotely.
/**
* Test to make sure that invokeRemotely returns the result from the remote side.
*/
public void testInvokeRemotely() {
RpcManager rpcManager = cache(0, "testCache").getAdvancedCache().getRpcManager();
ReplicableCommand command = createReplicableCommandForTest(EXPECTED_RETURN_VALUE);
Map<Address, Response> remoteResponses = invoke(rpcManager, command);
log.tracef("Responses were: %s", remoteResponses);
assertEquals(1, remoteResponses.size());
Response response = remoteResponses.values().iterator().next();
assertNotNull(response);
assertTrue(response.isValid());
assertTrue(response.isSuccessful());
assertTrue(response instanceof SuccessfulResponse);
Object value = ((SuccessfulResponse) response).getResponseValue();
assertEquals(EXPECTED_RETURN_VALUE, value);
}
use of org.infinispan.remoting.responses.SuccessfulResponse in project infinispan by infinispan.
the class PrefetchInterceptor method handleRemotelyPrefetchedEntry.
private Object handleRemotelyPrefetchedEntry(InvocationContext ctx, VisitableCommand command, Object rv) {
Map<Address, Response> responseMap = (Map<Address, Response>) rv;
EntryVersion maxVersion = null;
InternalCacheValue<V> maxValue = null;
for (Response response : responseMap.values()) {
if (!response.isSuccessful()) {
throw OutdatedTopologyException.RETRY_NEXT_TOPOLOGY;
}
SuccessfulResponse<InternalCacheValue<V>> successfulResponse = (SuccessfulResponse<InternalCacheValue<V>>) response;
InternalCacheValue<V> icv = successfulResponse.getResponseValue();
if (icv == null) {
continue;
}
Metadata metadata = icv.getMetadata();
if (metadata instanceof RemoteMetadata) {
// from another node is possible.
throw OutdatedTopologyException.RETRY_NEXT_TOPOLOGY;
}
if (metadata != null && metadata.version() != null) {
if (maxVersion == null || maxVersion.compareTo(metadata.version()) == InequalVersionComparisonResult.BEFORE) {
maxVersion = metadata.version();
maxValue = icv;
}
}
}
if (log.isTraceEnabled()) {
log.tracef("Prefetched value is %s", maxValue);
}
DataCommand dataCommand = (DataCommand) command;
if (maxValue == null) {
return null;
}
// The put below could fail updating the context if the data container got the updated value while we were
// prefetching that (then the version would not be higher than the on in DC).
// We need to call RepeatableReadEntry.updatePreviousValue() (through wrapExternalEntry) to get return value
// from the main comman d correct.
entryFactory.wrapExternalEntry(ctx, dataCommand.getKey(), maxValue.toInternalCacheEntry(dataCommand.getKey()), true, true);
PutKeyValueCommand putKeyValueCommand = commandsFactory.buildPutKeyValueCommand(dataCommand.getKey(), maxValue.getValue(), dataCommand.getSegment(), new InternalMetadataImpl(maxValue), STATE_TRANSFER_FLAGS);
putKeyValueCommand.setTopologyId(dataCommand.getTopologyId());
return invokeNext(ctx, putKeyValueCommand);
}
use of org.infinispan.remoting.responses.SuccessfulResponse in project infinispan by infinispan.
the class RecoveryManagerImpl method getPreparedTransactionsFromCluster.
@Override
public RecoveryIterator getPreparedTransactionsFromCluster() {
PreparedTxIterator iterator = new PreparedTxIterator();
// 1. get local transactions first
// add the locally prepared transactions. The list of prepared transactions (even if they are not in-doubt)
// is mandated by the recovery process according to the JTA spec: "The transaction manager calls this [i.e. recover]
// method during recovery to obtain the list of transaction branches that are currently in prepared or heuristically
// completed states."
iterator.add((recoveryAwareTxTable()).getLocalPreparedXids());
// 2. now also add the in-doubt transactions.
iterator.add(getInDoubtTransactions());
// 3. then the remote ones
if (notOnlyMeInTheCluster() && broadcastForPreparedTx) {
boolean success = true;
Map<Address, Response> responses = getAllPreparedTxFromCluster();
for (Map.Entry<Address, Response> rEntry : responses.entrySet()) {
Response thisResponse = rEntry.getValue();
if (isSuccessful(thisResponse)) {
// noinspection unchecked
List<XidImpl> responseValue = ((SuccessfulResponse<List<XidImpl>>) thisResponse).getResponseValue();
if (log.isTraceEnabled()) {
log.tracef("Received Xid lists %s from node %s", responseValue, rEntry.getKey());
}
iterator.add(responseValue);
} else {
log.missingListPreparedTransactions(rEntry.getKey(), rEntry.getValue());
success = false;
}
}
// this makes sure that the broadcast only happens once!
this.broadcastForPreparedTx = !success;
if (!broadcastForPreparedTx)
log.debug("Finished broadcasting for remote prepared transactions. Returning only local values from now on.");
}
return iterator;
}
use of org.infinispan.remoting.responses.SuccessfulResponse in project infinispan by infinispan.
the class TopologyManagementHelper method executeOnCoordinator.
public CompletionStage<Object> executeOnCoordinator(Transport transport, ReplicableCommand command, long timeoutMillis) {
CompletionStage<? extends Response> responseStage;
Address coordinator = transport.getCoordinator();
if (transport.getAddress().equals(coordinator)) {
try {
if (log.isTraceEnabled())
log.tracef("Attempting to execute command on self: %s", command);
bcr.wireDependencies(command, true);
responseStage = invokeAsync(command).thenApply(v -> makeResponse(v, null, transport.getAddress()));
} catch (Throwable t) {
throw CompletableFutures.asCompletionException(t);
}
} else {
// this node is not the coordinator
responseStage = transport.invokeCommand(coordinator, command, SingleResponseCollector.validOnly(), DeliverOrder.NONE, timeoutMillis, TimeUnit.MILLISECONDS);
}
return responseStage.thenApply(response -> {
if (!(response instanceof SuccessfulResponse)) {
throw CLUSTER.unexpectedResponse(coordinator, response);
}
return ((SuccessfulResponse) response).getResponseValue();
});
}
Aggregations