package org.infinispan.client.hotrod;
import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.getLoadBalancer;
import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
import static org.testng.AssertJUnit.assertEquals;
import java.net.SocketAddress;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import org.infinispan.client.hotrod.impl.transport.tcp.RoundRobinBalancingStrategy;
import org.infinispan.client.hotrod.test.HotRodClientTestingUtil;
import org.infinispan.client.hotrod.test.MultiHotRodServersTest;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.server.hotrod.HotRodServer;
import org.infinispan.test.TestingUtil;
import org.testng.annotations.Test;
@Test(groups = "functional", testName = "client.hotrod.DistTopologyChangeUnderLoadTest")
public class DistTopologyChangeUnderLoadTest extends MultiHotRodServersTest {
@Override
protected void createCacheManagers() throws Throwable {
createHotRodServers(1, getCacheConfiguration());
}
private ConfigurationBuilder getCacheConfiguration() {
ConfigurationBuilder builder = getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false);
builder.clustering().hash().numOwners(2);
return hotRodCacheConfiguration(builder);
}
@Override
protected int maxRetries() {
return 1;
}
public void testPutsSucceedWhileTopologyChanges() throws Exception {
RemoteCache<Integer, String> remote = client(0).getCache();
remote.put(1, "v1");
assertEquals("v1", remote.get(1));
PutHammer putHammer = new PutHammer();
Future<Void> putHammerFuture = fork(putHammer);
HotRodServer newServer = addHotRodServer(getCacheConfiguration());
// Wait for 2 seconds
TestingUtil.sleepThread(2000);
HotRodClientTestingUtil.killServers(newServer);
TestingUtil.killCacheManagers(newServer.getCacheManager());
TestingUtil.waitForNoRebalance(cache(0));
// Execute one more operation to guarantee topology update on the client
remote.put(-1, "minus one");
RoundRobinBalancingStrategy strategy = getLoadBalancer(client(0));
SocketAddress[] servers = strategy.getServers();
putHammer.stop = true;
putHammerFuture.get();
assertEquals(1, servers.length);
}
private class PutHammer implements Callable<Void> {
volatile boolean stop;
@Override
public Void call() throws Exception {
RemoteCache<Integer, String> remote = client(0).getCache();
int i = 2;
while (!stop) {
remote.put(i, "v" + i);
i += 1;
}
// Rehash completed only signals that server side caches have
// completed, but the client might not yet have updated its topology.
// So, run a fair few operations after rehashing has completed server
// side to verify it's all working fine.
for (int j = i + 1; j < i + 100 ; j++)
remote.put(j, "v" + j);
return null;
}
}
}