use of org.infinispan.distribution.MagicKey in project infinispan by infinispan.
the class BaseTxStateTransferOverwriteTest method doL1InvalidationOldTopologyComesAfterRebalance.
private void doL1InvalidationOldTopologyComesAfterRebalance(final TestWriteOperation op) throws Exception {
// Test scenario:
// cache0,1,2 are in the cluster, an owner leaves
// Key k is in the cache, and is transferred to the non owner
// A user operation also modifies key k causing an invalidation
// on the non owner which is getting the state transfer
final AdvancedCache<Object, Object> primaryOwnerCache = advancedCache(0, cacheName);
final AdvancedCache<Object, Object> backupOwnerCache = advancedCache(1, cacheName);
final AdvancedCache<Object, Object> nonOwnerCache = advancedCache(2, cacheName);
final MagicKey key = new MagicKey(op + "-key", cache(0, cacheName), cache(1, cacheName));
// Prepare for replace/remove: put a previous value in cache0
final Object previousValue = op.getPreviousValue();
if (previousValue != null) {
primaryOwnerCache.put(key, previousValue);
assertEquals(previousValue, primaryOwnerCache.get(key));
log.tracef("Previous value inserted: %s = %s", key, previousValue);
assertEquals(previousValue, nonOwnerCache.get(key));
if (l1Enabled()) {
assertIsInL1(nonOwnerCache, key);
}
}
// Block on the interceptor right after ST which should now have the soon to be old topology id
CyclicBarrier beforeCommitCache1Barrier = new CyclicBarrier(2);
BlockingInterceptor<?> blockingInterceptor1 = new BlockingInterceptor<>(beforeCommitCache1Barrier, getVisitableCommand(op), false, false);
extractInterceptorChain(primaryOwnerCache).addInterceptorAfter(blockingInterceptor1, StateTransferInterceptor.class);
// Put/Replace/Remove from primary owner. This will block before it is committing on remote nodes
Future<Object> future = fork(() -> {
try {
return op.perform(primaryOwnerCache, key);
} finally {
log.tracef("%s operation is done", op);
}
});
beforeCommitCache1Barrier.await(10, SECONDS);
// Remove blocking interceptor now since we have blocked
removeAllBlockingInterceptorsFromCache(primaryOwnerCache);
// Remove the leaver
log.tracef("Stopping the cache");
backupOwnerCache.getCacheManager().stop();
// Wait for the write CH to contain the joiner everywhere
eventually(() -> primaryOwnerCache.getRpcManager().getMembers().size() == 2 && nonOwnerCache.getRpcManager().getMembers().size() == 2);
TestingUtil.waitForNoRebalance(primaryOwnerCache, nonOwnerCache);
// Now let the update go through
beforeCommitCache1Barrier.await(10, SECONDS);
// Run the update now that we are in the middle of a rebalance
assertEquals(op.getReturnValue(), future.get(10, SECONDS));
log.tracef("%s operation is done", op);
switch(op) {
case REMOVE:
case REMOVE_EXACT:
break;
default:
assertIsInContainerImmortal(primaryOwnerCache, key);
assertIsInContainerImmortal(nonOwnerCache, key);
break;
}
// Check the value to make sure data container contains correct value
assertEquals(op.getValue(), primaryOwnerCache.get(key));
assertEquals(op.getValue(), nonOwnerCache.get(key));
}
use of org.infinispan.distribution.MagicKey in project infinispan by infinispan.
the class RehashWithSharedStoreTest method testRehashes.
public void testRehashes() throws PersistenceException {
MagicKey k = new MagicKey("k", c1);
c1.put(k, "v");
Cache<Object, String>[] owners = getOwners(k);
log.infof("Initial owners list for key %s: %s", k, Arrays.asList(owners));
// Ensure the loader is shared!
for (Cache<Object, String> c : Arrays.asList(c1, c2, c3)) {
DummyInMemoryStore dims = TestingUtil.getFirstStore(c);
assertTrue("CacheStore on " + c + " should contain key " + k, dims.contains(k));
}
Cache<Object, String> primaryOwner = owners[0];
if (getCacheStoreStats(primaryOwner, "write") == 0)
primaryOwner = owners[1];
for (Cache<Object, String> c : owners) {
int numWrites = getCacheStoreStats(c, "write");
assertEquals(1, numWrites);
}
log.infof("Stopping node %s", primaryOwner);
caches.remove(primaryOwner);
primaryOwner.stop();
primaryOwner.getCacheManager().stop();
TestingUtil.blockUntilViewsReceived(60000, false, caches);
TestingUtil.waitForNoRebalance(caches);
owners = getOwners(k);
log.infof("After shutting one node down, owners list for key %s: %s", k, Arrays.asList(owners));
assertEquals(numOwners, owners.length);
for (Cache<Object, String> o : owners) {
int numWrites = getCacheStoreStats(o, "write");
assertEquals(1, numWrites);
assertEquals("v", o.get(k));
}
}
use of org.infinispan.distribution.MagicKey in project infinispan by infinispan.
the class StateResponseOrderingTest method testStateResponseWhileRestartingBrokenTransfers.
public void testStateResponseWhileRestartingBrokenTransfers() throws Throwable {
// The initial topology is different from the other method's
consistentHashFactory.setOwnerIndexes(new int[][] { { 1, 2, 3 }, { 2, 1, 3 } });
consistentHashFactory.triggerRebalance(cache(0));
// waitForStableTopology doesn't work here, since the cache looks already "balanced"
// So we wait for the primary owner of segment 1 to change
eventuallyEquals(address(2), () -> advancedCache(0).getDistributionManager().getReadConsistentHash().locatePrimaryOwnerForSegment(1));
// See https://issues.jboss.org/browse/ISPN-3120?focusedCommentId=12777231
// Start with segment 0 owned by [cache1, cache2, cache3], and segment 1 owned by [cache2, cache1, cache3]
// Trigger a rebalance with cache0 becoming an owner for both segments
// Wait for either cache1 or cache2 to send a StateResponseCommand
// Block the state response on cache0
// Kill the node that didn't receive the request
// Block new state requests from cache0 so that the killed node's segment doesn't have a transfer task
// Unblock the first state response
// Check that the StateResponseCommand hasn't marked state transfer as completed
// Unblock the new state request
// Wait for the state transfer to end and check that state hasn't been lost
StateSequencer sequencer = new StateSequencer();
sequencer.logicalThread("st", "st:block_first_state_response", "st:kill_node", "st:block_second_state_request", "st:resume_first_state_response", "st:after_first_state_response", "st:check_incomplete", "st:resume_second_state_request");
final AtomicReference<Address> firstResponseSender = new AtomicReference<>();
CommandMatcher firstStateResponseMatcher = new CommandMatcher() {
CommandMatcher realMatcher = matchCommand(StateResponseCommand.class).matchCount(0).build();
public boolean accept(ReplicableCommand command) {
if (!realMatcher.accept(command))
return false;
firstResponseSender.set(((StateResponseCommand) command).getOrigin());
return true;
}
};
advanceOnInboundRpc(sequencer, cache(0), firstStateResponseMatcher).before("st:block_first_state_response", "st:resume_first_state_response").after("st:after_first_state_response");
CommandMatcher secondStateRequestMatcher = new CommandMatcher() {
private final AtomicInteger counter = new AtomicInteger();
@Override
public boolean accept(ReplicableCommand command) {
if (command instanceof StateTransferGetTransactionsCommand) {
// Command 2 is the first sent after the node is killed
if (counter.getAndIncrement() == 2)
return true;
log.debugf("Not blocking command %s", command);
}
return false;
}
};
advanceOnOutboundRpc(sequencer, cache(0), secondStateRequestMatcher).before("st:block_second_state_request", "st:resume_second_state_request");
DistributionManager dm0 = advancedCache(0).getDistributionManager();
StateTransferManager stm0 = TestingUtil.extractComponentRegistry(cache(0)).getStateTransferManager();
MagicKey k1 = new MagicKey("k1", cache(1));
assertEquals(Arrays.asList(address(1), address(2), address(3)), dm0.getCacheTopology().getDistribution(k1).readOwners());
cache(0).put(k1, "v1");
MagicKey k2 = new MagicKey("k2", cache(2));
assertEquals(Arrays.asList(address(2), address(1), address(3)), dm0.getCacheTopology().getDistribution(k2).readOwners());
cache(0).put(k2, "v2");
// Start the rebalance
consistentHashFactory.setOwnerIndexes(new int[][] { { 0, 1, 2 }, { 0, 2, 1 } });
consistentHashFactory.triggerRebalance(cache(0));
// Wait for cache0 to receive the state response
sequencer.enter("st:kill_node");
assertNotNull(dm0.getCacheTopology().getPendingCH());
// No need to update the owner indexes, the CH factory only knows about the cache members
int nodeToKeep = managerIndex(firstResponseSender.get());
int nodeToKill = nodeToKeep == 1 ? 2 : 1;
log.debugf("Blocked state response from %s, killing %s", firstResponseSender.get(), manager(nodeToKill));
cache(nodeToKill).stop();
eventuallyEquals(3, () -> dm0.getCacheTopology().getMembers().size());
sequencer.exit("st:kill_node");
sequencer.enter("st:check_incomplete");
assertTrue(stm0.isStateTransferInProgress());
sequencer.exit("st:check_incomplete");
// Only the 3 live caches are in the collection, wait for the rehash to end
waitForNoRebalance(cache(0), cache(nodeToKeep), cache(3));
assertTrue(dm0.getCacheTopology().isReadOwner(k1));
assertTrue(dm0.getCacheTopology().isReadOwner(k2));
assertEquals("v1", cache(0).get(k1));
assertEquals("v2", cache(0).get(k2));
}
use of org.infinispan.distribution.MagicKey in project infinispan by infinispan.
the class RehashCompletedOnJoinTest method testJoinComplete.
public void testJoinComplete() {
List<MagicKey> keys = new ArrayList<MagicKey>(Arrays.asList(new MagicKey("k1", c1), new MagicKey("k2", c2), new MagicKey("k3", c1), new MagicKey("k4", c2)));
int i = 0;
for (Cache<Object, String> c : caches) c.put(keys.get(i++), "v" + i);
log.infof("Initialized with keys %s", keys);
EmbeddedCacheManager joinerManager = addClusterEnabledCacheManager(TestDataSCI.INSTANCE);
joinerManager.defineConfiguration(cacheName, configuration.build());
Cache joiner = joinerManager.getCache(cacheName);
DistributionManager dmi = joiner.getAdvancedCache().getDistributionManager();
assert dmi.isJoinComplete();
}
use of org.infinispan.distribution.MagicKey in project infinispan by infinispan.
the class Updater method testNonTransactional.
/**
* Simple test. Put some state, trigger event, test results
*/
@Test
public void testNonTransactional() throws Throwable {
List<MagicKey> keys = init();
log.info("Invoking rehash event");
performRehashEvent(false);
waitForRehashCompletion();
log.info("Rehash complete");
for (MagicKey key : keys) assertOnAllCachesAndOwnership(key, "v0");
}
Aggregations