use of org.infinispan.container.versioning.IncrementableEntryVersion in project infinispan by infinispan.
the class WriteSkewHelper method performWriteSkewCheckAndReturnNewVersions.
public static CompletionStage<Map<Object, IncrementableEntryVersion>> performWriteSkewCheckAndReturnNewVersions(VersionedPrepareCommand prepareCommand, EntryLoader<?, ?> entryLoader, VersionGenerator versionGenerator, TxInvocationContext<?> context, KeySpecificLogic ksl, KeyPartitioner keyPartitioner) {
if (prepareCommand.getVersionsSeen() == null) {
// Do not perform the write skew check if this prepare command is being replayed for state transfer
return CompletableFutures.completedEmptyMap();
}
Map<Object, IncrementableEntryVersion> uv = new HashMap<>();
AggregateCompletionStage<Map<Object, IncrementableEntryVersion>> aggregateCompletionStage = CompletionStages.aggregateCompletionStage(uv);
for (WriteCommand c : prepareCommand.getModifications()) {
for (Object k : c.getAffectedKeys()) {
int segment = SegmentSpecificCommand.extractSegment(c, k, keyPartitioner);
if (ksl.performCheckOnSegment(segment)) {
CacheEntry<?, ?> cacheEntry = context.lookupEntry(k);
if (!(cacheEntry instanceof VersionedRepeatableReadEntry)) {
continue;
}
VersionedRepeatableReadEntry entry = (VersionedRepeatableReadEntry) cacheEntry;
CompletionStage<Boolean> skewStage = entry.performWriteSkewCheck(entryLoader, segment, context, prepareCommand.getVersionsSeen().get(k), versionGenerator, c.hasAnyFlag(FlagBitSets.ROLLING_UPGRADE));
aggregateCompletionStage.dependsOn(skewStage.thenAccept(passSkew -> {
if (!passSkew) {
throw new WriteSkewException("Write skew detected on key " + entry.getKey() + " for transaction " + context.getCacheTransaction(), entry.getKey());
}
IncrementableEntryVersion newVersion = incrementVersion(entry, versionGenerator);
// Have to synchronize as we could have returns on different threads due to notifications/loaders etc
synchronized (uv) {
uv.put(entry.getKey(), newVersion);
}
}));
}
}
}
return aggregateCompletionStage.freeze();
}
use of org.infinispan.container.versioning.IncrementableEntryVersion in project infinispan by infinispan.
the class TxDistributionInterceptor method checkCacheNotFoundResponseInPartitionHandling.
private boolean checkCacheNotFoundResponseInPartitionHandling(TransactionBoundaryCommand command, TxInvocationContext<LocalTransaction> context, Collection<Address> recipients) {
final GlobalTransaction globalTransaction = command.getGlobalTransaction();
final Collection<Object> lockedKeys = context.getLockedKeys();
if (command instanceof RollbackCommand) {
return partitionHandlingManager.addPartialRollbackTransaction(globalTransaction, recipients, lockedKeys);
} else if (command instanceof PrepareCommand) {
if (((PrepareCommand) command).isOnePhaseCommit()) {
return partitionHandlingManager.addPartialCommit1PCTransaction(globalTransaction, recipients, lockedKeys, Arrays.asList(((PrepareCommand) command).getModifications()));
}
} else if (command instanceof CommitCommand) {
Map<Object, IncrementableEntryVersion> newVersion = null;
if (command instanceof VersionedCommitCommand) {
newVersion = ((VersionedCommitCommand) command).getUpdatedVersions();
}
return partitionHandlingManager.addPartialCommit2PCTransaction(globalTransaction, recipients, lockedKeys, newVersion);
}
return false;
}
use of org.infinispan.container.versioning.IncrementableEntryVersion in project infinispan by infinispan.
the class EntryWrappingInterceptor method addVersionRead.
private void addVersionRead(TxInvocationContext<?> rCtx, CacheEntry<?, ?> cacheEntry, Object key) {
IncrementableEntryVersion version = versionFromEntry(cacheEntry);
if (version == null) {
version = versionGenerator.nonExistingVersion();
if (log.isTraceEnabled()) {
log.tracef("Adding non-existent version read for key %s", key);
}
} else if (log.isTraceEnabled()) {
log.tracef("Adding version read %s for key %s", version, key);
}
rCtx.getCacheTransaction().addVersionRead(key, version);
}
use of org.infinispan.container.versioning.IncrementableEntryVersion in project infinispan by infinispan.
the class IracWriteSkewTest method checkKey.
private void checkKey(String key, String value) {
// irac version is the same in all nodes & sites. extract it from one site and check everywhere.
IracEntryVersion iracVersion = extractIracEntryVersion(key);
assertNotNull(iracVersion);
assertIracEntryVersion(key, value, iracVersion);
// NYC has the EntryVersion for write-skew check
IncrementableEntryVersion entryVersion = extractEntryVersion(key);
assertNotNull(entryVersion);
assertIracEntryVersion(key, value, iracVersion, entryVersion);
}
use of org.infinispan.container.versioning.IncrementableEntryVersion in project infinispan by infinispan.
the class VersionedDistributionInterceptor method wrapFunctionalManyResultOnNonOrigin.
@Override
protected Object wrapFunctionalManyResultOnNonOrigin(InvocationContext ctx, Collection<?> keys, Object[] values) {
// note: this relies on the fact that keys are already ordered on remote node
EntryVersion[] versions = new EntryVersion[keys.size()];
int i = 0;
for (Object key : keys) {
IncrementableEntryVersion version = versionFromEntry(ctx.lookupEntry(key));
versions[i++] = version == null ? versionGenerator.nonExistingVersion() : version;
}
return new VersionedResults(values, versions);
}
Aggregations