@Override public void broadcastTopologyUpdate( String cacheName, CacheTopology cacheTopology, AvailabilityMode availabilityMode, boolean totalOrder, boolean distributed) { instance.broadcastTopologyUpdate( cacheName, cacheTopology, availabilityMode, totalOrder, distributed); }
@Override public org.infinispan.topology.CacheStatusResponse handleJoin( String cacheName, Address joiner, CacheJoinInfo joinInfo, int viewId) throws Exception { CacheStatusResponse result = instance.handleJoin(cacheName, joiner, joinInfo, viewId); // Allow the joiner to receive some commands before the initial cache topology log.tracef("Delaying join response"); Thread.sleep(500); return result; }
@Override public void broadcastRebalanceStart( String cacheName, CacheTopology cacheTopology, boolean totalOrder, boolean distributed) { // Allow the joiner to receive some commands between the initial cache topology and the // rebalance start log.tracef("Delaying rebalance"); try { Thread.sleep(500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } instance.broadcastRebalanceStart(cacheName, cacheTopology, totalOrder, distributed); }
public void testReplace() throws Exception { cache(0).put("myKey", "myValue"); // add an interceptor on second node that will block REPLACE commands right after // EntryWrappingInterceptor until we are ready final CountDownLatch replaceStartedLatch = new CountDownLatch(1); final CountDownLatch replaceProceedLatch = new CountDownLatch(1); boolean isVersioningEnabled = cache(0).getCacheConfiguration().versioning().enabled(); cacheConfigBuilder .customInterceptors() .addInterceptor() .after( isVersioningEnabled ? VersionedEntryWrappingInterceptor.class : EntryWrappingInterceptor.class) .interceptor( new CommandInterceptor() { @Override protected Object handleDefault(InvocationContext ctx, VisitableCommand cmd) throws Throwable { if (cmd instanceof ReplaceCommand) { // signal we encounter a REPLACE replaceStartedLatch.countDown(); // wait until it is ok to continue with REPLACE if (!replaceProceedLatch.await(15, TimeUnit.SECONDS)) { throw new TimeoutException(); } } return super.handleDefault(ctx, cmd); } }); // do not allow coordinator to send topology updates to node B final ClusterTopologyManager ctm0 = TestingUtil.extractGlobalComponent(manager(0), ClusterTopologyManager.class); ctm0.setRebalancingEnabled(false); log.info("Adding a new node .."); addClusterEnabledCacheManager(cacheConfigBuilder); log.info("Added a new node"); // node B is not a member yet and rebalance has not started yet CacheTopology cacheTopology = advancedCache(1).getComponentRegistry().getStateTransferManager().getCacheTopology(); assertNull(cacheTopology.getPendingCH()); assertTrue(cacheTopology.getMembers().contains(address(0))); assertFalse(cacheTopology.getMembers().contains(address(1))); assertFalse(cacheTopology.getCurrentCH().getMembers().contains(address(1))); // no keys should be present on node B yet because state transfer is blocked assertTrue(cache(1).keySet().isEmpty()); // initiate a REPLACE Future<Object> getFuture = fork( new Callable<Object>() { @Override public Object call() throws Exception { try { return cache(1).replace("myKey", "newValue"); } catch (Exception e) { log.errorf(e, "REPLACE failed: %s", e.getMessage()); throw e; } } }); // wait for REPLACE command on node B to reach beyond *EntryWrappingInterceptor, where it will // block. // the value seen so far is null if (!replaceStartedLatch.await(15, TimeUnit.SECONDS)) { throw new TimeoutException(); } // paranoia, yes the value is still missing from data container assertTrue(cache(1).keySet().isEmpty()); // allow rebalance to start ctm0.setRebalancingEnabled(true); // wait for state transfer to end TestingUtil.waitForRehashToComplete(cache(0), cache(1)); // the state should be already transferred now assertEquals(1, cache(1).keySet().size()); // allow REPLACE to continue replaceProceedLatch.countDown(); Object oldVal = getFuture.get(15, TimeUnit.SECONDS); assertNotNull(oldVal); assertEquals("myValue", oldVal); assertEquals("newValue", cache(0).get("myKey")); assertEquals("newValue", cache(1).get("myKey")); }
@Override public void forceAvailabilityMode(String cacheName, AvailabilityMode availabilityMode) { instance.forceAvailabilityMode(cacheName, availabilityMode); }
@Override public void forceRebalance(String cacheName) { instance.forceRebalance(cacheName); }
@Override public void setRebalancingEnabled(boolean enabled) { instance.setRebalancingEnabled(enabled); }
@Override public boolean isRebalancingEnabled() { return instance.isRebalancingEnabled(); }
@Override public void broadcastStableTopologyUpdate( String cacheName, CacheTopology cacheTopology, boolean totalOrder, boolean distributed) { instance.broadcastStableTopologyUpdate(cacheName, cacheTopology, totalOrder, distributed); }
@Override public void handleClusterView(boolean isMerge, int viewId) { instance.handleClusterView(isMerge, viewId); }
@Override public void handleRebalanceCompleted( String cacheName, Address node, int topologyId, Throwable throwable, int viewId) throws Exception { instance.handleRebalanceCompleted(cacheName, node, topologyId, throwable, viewId); }
@Override public void handleLeave(String cacheName, Address leaver, int viewId) throws Exception { instance.handleLeave(cacheName, leaver, viewId); }