use of org.infinispan.statetransfer.StateTransferLock in project infinispan by infinispan.
the class BaseDistSyncL1Test method waitUntilAboutToAcquireLock.
/**
* Replaces StateTransferLock in cache with a proxy one that will block on
* {#link StateTransferLock#acquireSharedTopologyLock} until the checkpoint is triggered
* @param cache The cache to replace the StateTransferLock on
* @param checkPoint The checkpoint to use to trigger blocking
* @return The original real StateTransferLock
*/
protected StateTransferLock waitUntilAboutToAcquireLock(final Cache<?, ?> cache, final CheckPoint checkPoint) {
StateTransferLock stl = TestingUtil.extractComponent(cache, StateTransferLock.class);
final Answer<Object> forwardedAnswer = AdditionalAnswers.delegatesTo(stl);
StateTransferLock mockLock = mock(StateTransferLock.class, withSettings().defaultAnswer(forwardedAnswer));
doAnswer(invocation -> {
// Wait for main thread to sync up
checkPoint.trigger("pre_acquire_shared_topology_lock_invoked");
// Now wait until main thread lets us through
checkPoint.awaitStrict("pre_acquire_shared_topology_lock_released", 10, TimeUnit.SECONDS);
return forwardedAnswer.answer(invocation);
}).when(mockLock).acquireSharedTopologyLock();
TestingUtil.replaceComponent(cache, StateTransferLock.class, mockLock, true);
return stl;
}
use of org.infinispan.statetransfer.StateTransferLock in project infinispan by infinispan.
the class BaseDistSyncL1Test method testGetBlockingAnotherGet.
@Test
public void testGetBlockingAnotherGet() throws Throwable {
final Cache<Object, String> nonOwnerCache = getFirstNonOwner(key);
final Cache<Object, String> ownerCache = getFirstOwner(key);
ownerCache.put(key, firstValue);
assertIsNotInL1(nonOwnerCache, key);
CheckPoint checkPoint = new CheckPoint();
StateTransferLock lock = waitUntilAboutToAcquireLock(nonOwnerCache, checkPoint);
try {
log.warn("Doing get here - ignore all previous");
Future<String> getFuture = fork(() -> nonOwnerCache.get(key));
// Wait until we are about to write value into data container on non owner
checkPoint.awaitStrict("pre_acquire_shared_topology_lock_invoked", 10, TimeUnit.SECONDS);
Future<String> getFuture2 = fork(() -> nonOwnerCache.get(key));
Exceptions.expectException(TimeoutException.class, () -> getFuture2.get(1, TimeUnit.SECONDS));
// Let the get complete finally
checkPoint.triggerForever("pre_acquire_shared_topology_lock_released");
assertEquals(firstValue, getFuture.get(10, TimeUnit.SECONDS));
assertEquals(firstValue, getFuture2.get(10, TimeUnit.SECONDS));
assertIsInL1(nonOwnerCache, key);
} finally {
TestingUtil.replaceComponent(nonOwnerCache, StateTransferLock.class, lock, true);
}
}
use of org.infinispan.statetransfer.StateTransferLock in project infinispan by infinispan.
the class GetAllCacheNotFoundResponseTest method simulateTopologyUpdate.
private Future<Void> simulateTopologyUpdate(Cache<Object, Object> cache) {
StateTransferLock stl4 = TestingUtil.extractComponent(cache, StateTransferLock.class);
DistributionManager dm4 = cache.getAdvancedCache().getDistributionManager();
LocalizedCacheTopology cacheTopology = dm4.getCacheTopology();
int newTopologyId = cacheTopology.getTopologyId() + 1;
CacheTopology newTopology = new CacheTopology(newTopologyId, cacheTopology.getRebalanceId(), cacheTopology.getCurrentCH(), cacheTopology.getPendingCH(), cacheTopology.getUnionCH(), cacheTopology.getPhase(), cacheTopology.getActualMembers(), cacheTopology.getMembersPersistentUUIDs());
dm4.setCacheTopology(newTopology);
return fork(() -> stl4.notifyTransactionDataReceived(newTopologyId));
}
use of org.infinispan.statetransfer.StateTransferLock in project infinispan by infinispan.
the class BaseDistSyncL1Test method testGetBlockingAnotherGetCacheEntry.
@Test
public void testGetBlockingAnotherGetCacheEntry() throws Throwable {
final Cache<Object, String> nonOwnerCache = getFirstNonOwner(key);
final Cache<Object, String> ownerCache = getFirstOwner(key);
ownerCache.put(key, firstValue);
assertIsNotInL1(nonOwnerCache, key);
CheckPoint checkPoint = new CheckPoint();
StateTransferLock lock = waitUntilAboutToAcquireLock(nonOwnerCache, checkPoint);
try {
log.warn("Doing get here - ignore all previous");
Future<String> getFuture = fork(() -> nonOwnerCache.get(key));
// Wait until we are about to write value into data container on non owner
checkPoint.awaitStrict("pre_acquire_shared_topology_lock_invoked", 10, TimeUnit.SECONDS);
Future<CacheEntry<Object, String>> getFuture2 = fork(() -> nonOwnerCache.getAdvancedCache().getCacheEntry(key));
Exceptions.expectException(TimeoutException.class, () -> getFuture2.get(1, TimeUnit.SECONDS));
// Let the get complete finally
checkPoint.triggerForever("pre_acquire_shared_topology_lock_released");
assertEquals(firstValue, getFuture.get(10, TimeUnit.SECONDS));
CacheEntry<Object, String> entry = getFuture2.get(10, TimeUnit.SECONDS);
assertEquals(key, entry.getKey());
assertEquals(firstValue, entry.getValue());
assertIsInL1(nonOwnerCache, key);
} finally {
TestingUtil.replaceComponent(nonOwnerCache, StateTransferLock.class, lock, true);
}
}
use of org.infinispan.statetransfer.StateTransferLock in project infinispan by infinispan.
the class InvalidateVersionsCommand method invokeAsync.
@Override
public CompletionStage<?> invokeAsync(ComponentRegistry componentRegistry) {
StateTransferLock stateTransferLock = componentRegistry.getStateTransferLock();
if (stateTransferLock != null) {
stateTransferLock.acquireSharedTopologyLock();
}
try {
DistributionManager distributionManager = componentRegistry.getDistributionManager();
if (topologyId >= 0 && distributionManager != null) {
int currentTopologyId = distributionManager.getCacheTopology().getTopologyId();
if (topologyId > currentTopologyId) {
if (log.isTraceEnabled()) {
log.tracef("Delaying command %s, current topology id %d", this, currentTopologyId);
}
return stateTransferLock.topologyFuture(topologyId).thenCompose(nil -> invokeAsync(componentRegistry));
} else if (topologyId < currentTopologyId) {
log.ignoringInvalidateVersionsFromOldTopology(this.topologyId, currentTopologyId);
if (log.isTraceEnabled()) {
log.tracef("Ignored command is %s", this);
}
return CompletableFutures.completedNull();
}
}
for (int i = 0; i < keys.length; ++i) {
Object key = keys[i];
if (key == null)
break;
SimpleClusteredVersion version = new SimpleClusteredVersion(topologyIds[i], versions[i]);
BiasManager biasManager = componentRegistry.getBiasManager().running();
if (biasManager != null) {
biasManager.revokeLocalBias(key);
}
DataContainer dataContainer = componentRegistry.getInternalDataContainer().running();
dataContainer.compute(key, (k, oldEntry, factory) -> {
if (oldEntry == null) {
return null;
}
SimpleClusteredVersion localVersion = (SimpleClusteredVersion) oldEntry.getMetadata().version();
InequalVersionComparisonResult result = localVersion.compareTo(version);
if (result == InequalVersionComparisonResult.BEFORE || (removed && result == InequalVersionComparisonResult.EQUAL)) {
return null;
} else {
return oldEntry;
}
});
}
} finally {
if (stateTransferLock != null) {
stateTransferLock.releaseSharedTopologyLock();
}
}
OrderedUpdatesManager orderedUpdatesManager = componentRegistry.getOrderedUpdatesManager().running();
return orderedUpdatesManager.invalidate(keys).thenApply(nil -> null).toCompletableFuture();
}
Aggregations