use of org.infinispan.commands.DataCommand 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.commands.DataCommand in project infinispan by infinispan.
the class EntryWrappingInterceptor method checkTopology.
private LocalizedCacheTopology checkTopology(WriteCommand command, LocalizedCacheTopology commandTopology) {
int commandTopologyId = command.getTopologyId();
LocalizedCacheTopology currentTopology = distributionManager.getCacheTopology();
int currentTopologyId = currentTopology.getTopologyId();
// Can't perform the check during preload or if the cache isn't clustered
if (currentTopologyId == commandTopologyId || commandTopologyId == -1)
return currentTopology;
if (commandTopology != null) {
// commandTopology != null means the modification is already committed to the data container
// We want to retry the command if new owners were added since the command's topology,
// but if there are no new owners retrying won't help.
IntSet segments;
boolean ownersAdded;
if (command instanceof DataCommand) {
int segment = ((DataCommand) command).getSegment();
ownersAdded = segmentAddedOwners(commandTopology, currentTopology, segment);
} else {
segments = IntSets.mutableEmptySet(currentTopology.getNumSegments());
for (Object key : command.getAffectedKeys()) {
int segment = keyPartitioner.getSegment(key);
segments.set(segment);
}
ownersAdded = false;
for (int segment : segments) {
if (segmentAddedOwners(commandTopology, currentTopology, segment)) {
ownersAdded = true;
break;
}
}
}
if (!ownersAdded) {
if (log.isTraceEnabled())
log.tracef("Cache topology changed but no owners were added for keys %s", command.getAffectedKeys());
return null;
}
}
if (log.isTraceEnabled())
log.tracef("Cache topology changed while the command was executing: expected %d, got %d", commandTopologyId, currentTopologyId);
// This shouldn't be necessary, as we'll have a fresh command instance when retrying
command.setValueMatcher(command.getValueMatcher().matcherForRetry());
throw OutdatedTopologyException.RETRY_NEXT_TOPOLOGY;
}
Aggregations