public void testStressNodesLeavingWhileMultipleIteratorsLocalSegments() throws Throwable { testStressNodesLeavingWhilePerformingCallable((cache, masterValues, iteration) -> { Map<Integer, Integer> seenValues = new HashMap<>(); KeyPartitioner keyPartitioner = extractComponent(cache, KeyPartitioner.class); AdvancedCache<Integer, Integer> advancedCache = cache.getAdvancedCache(); LocalizedCacheTopology cacheTopology = advancedCache.getDistributionManager().getCacheTopology(); Set<Integer> targetSegments = cacheTopology.getWriteConsistentHash().getSegmentsForOwner(cacheTopology.getLocalAddress()); masterValues = masterValues.entrySet().stream() .filter(e -> targetSegments.contains(keyPartitioner.getSegment(e.getKey()))) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); Iterator<Map.Entry<Integer, Integer>> iterator = cache.entrySet().stream() .distributedBatchSize(50000) .filterKeySegments(targetSegments) .iterator(); while (iterator.hasNext()) { Map.Entry<Integer, Integer> entry = iterator.next(); if (seenValues.containsKey(entry.getKey())) { log.tracef("Seen values were: %s", seenValues); throw new IllegalArgumentException(Thread.currentThread() + "-Found duplicate value: " + entry.getKey() + " on iteration " + iteration); } else if (!masterValues.get(entry.getKey()).equals(entry.getValue())) { log.tracef("Seen values were: %s", seenValues); throw new IllegalArgumentException(Thread.currentThread() + "-Found incorrect value: " + entry.getKey() + " with value " + entry.getValue() + " on iteration " + iteration); } seenValues.put(entry.getKey(), entry.getValue()); } if (seenValues.size() != masterValues.size()) { findMismatchedSegments(keyPartitioner, masterValues, seenValues, iteration); } }); }
public MagicKey(String name, Cache<?, ?> primaryOwner, Cache<?, ?>... backupOwners) { this.name = name; Address primaryAddress = addressOf(primaryOwner); this.address = primaryAddress.toString(); LocalizedCacheTopology cacheTopology = primaryOwner.getAdvancedCache().getDistributionManager().getCacheTopology(); ConsistentHash ch = cacheTopology.getWriteConsistentHash(); segment = findSegment(ch.getNumSegments(), s -> { List<Address> owners = ch.locateOwnersForSegment(s); if (!primaryAddress.equals(owners.get(0))) return false; for (Cache<?, ?> backup : backupOwners) { if (!owners.contains(addressOf(backup))) return false; } return true; }); if (segment < 0) { throw new IllegalStateException("Could not find any segment owned by " + primaryOwner + ", " + Arrays.toString(backupOwners) + ", primary segments: " + segments(primaryOwner) + ", backup segments: " + Stream.of(backupOwners).collect(Collectors.toMap(Function.identity(), this::segments))); } hashcode = getHashCodeForSegment(cacheTopology, segment); unique = counter.getAndIncrement(); }
void performRehashEvent(boolean offline) { l1 = addressOf(c2); l2 = addressOf(c4); List<Address> killedNodes = Arrays.asList(l1, l2); CacheContainer cm2 = c2.getCacheManager(); CacheContainer cm4 = c4.getCacheManager(); Set<Integer> overlappingSegments = new HashSet<>(); ConsistentHash ch = getCacheTopology(c1).getWriteConsistentHash(); for (int segment = 0; segment < ch.getNumSegments(); segment++) { List<Address> owners = ch.locateOwnersForSegment(segment); if (owners.containsAll(killedNodes)) { overlappingSegments.add(segment); } } lostSegments = overlappingSegments; log.tracef("These segments will be lost after killing nodes %s: %s", killedNodes, lostSegments); cacheManagers.removeAll(Arrays.asList(cm2, cm4)); caches.removeAll(Arrays.asList(c2, c4)); TestingUtil.killCacheManagers(cm2, cm4); } }
public MagicKey(String name, Cache<?, ?> primaryOwner) { this.name = name; Address primaryAddress = addressOf(primaryOwner); this.address = primaryAddress.toString(); LocalizedCacheTopology cacheTopology = primaryOwner.getAdvancedCache().getDistributionManager().getCacheTopology(); ConsistentHash ch = cacheTopology.getWriteConsistentHash(); int segment = findSegment(ch.getNumSegments(), s -> primaryAddress.equals(ch.locatePrimaryOwnerForSegment(s))); if (segment < 0) { throw new IllegalStateException("Could not find any segment owned by " + primaryOwner + ", primary segments: " + segments(primaryOwner)); } this.segment = segment; hashcode = getHashCodeForSegment(cacheTopology, segment); unique = counter.getAndIncrement(); }
public void testJoinAndGet() { List<MagicKey> keys = init(); KeyPartitioner keyPartitioner = TestingUtil.extractComponent(c1, KeyPartitioner.class); ConsistentHash chOld = getCacheTopology(c1).getWriteConsistentHash(); Address joinerAddress = startNewMember(); List<Address> newMembers = new ArrayList<>(chOld.getMembers()); newMembers.add(joinerAddress); DefaultConsistentHashFactory chf = new DefaultConsistentHashFactory(); ConsistentHash chNew = chf.rebalance(chf.updateMembers((DefaultConsistentHash) chOld, newMembers, null)); // which key should me mapped to the joiner? MagicKey keyToTest = null; for (MagicKey k: keys) { int segment = keyPartitioner.getSegment(k); if (chNew.isSegmentLocalToNode(joinerAddress, segment)) { keyToTest = k; break; } } if (keyToTest == null) throw new NullPointerException("Couldn't find a key mapped to J!"); assert joiner.get(keyToTest) != null; } }