package org.infinispan.client.hotrod; import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager; import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers; import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; import org.apache.commons.pool.impl.GenericKeyedObjectPool; import org.infinispan.client.hotrod.impl.transport.tcp.TcpTransportFactory; import org.infinispan.client.hotrod.test.HotRodClientTestingUtil; import org.infinispan.commands.VisitableCommand; import org.infinispan.context.InvocationContext; import org.infinispan.interceptors.base.CommandInterceptor; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.server.hotrod.HotRodServer; import org.infinispan.test.SingleCacheManagerTest; import org.infinispan.test.TestingUtil; import org.infinispan.test.fwk.TestCacheManagerFactory; import org.testng.annotations.AfterClass; import org.testng.annotations.AfterMethod; import org.testng.annotations.Test; /** * @author Mircea.Markus@jboss.com * @since 4.1 */ @Test (testName = "client.hotrod.HeavyLoadConnectionPoolingTest", groups = "functional") public class HeavyLoadConnectionPoolingTest extends SingleCacheManagerTest { private HotRodServer hotRodServer; private RemoteCacheManager remoteCacheManager; private RemoteCache<Object, Object> remoteCache; private GenericKeyedObjectPool<?,?> connectionPool; @AfterMethod @Override protected void clearContent() { } @Override protected EmbeddedCacheManager createCacheManager() throws Exception { cacheManager = TestCacheManagerFactory.createCacheManager(hotRodCacheConfiguration()); cache = cacheManager.getCache(); // make sure all operations take at least 100 msecs cache.getAdvancedCache().addInterceptor(new ConstantDelayTransportInterceptor(100), 0); hotRodServer = HotRodClientTestingUtil.startHotRodServer(cacheManager); org.infinispan.client.hotrod.configuration.ConfigurationBuilder clientBuilder = new org.infinispan.client.hotrod.configuration.ConfigurationBuilder(); clientBuilder .connectionPool() .timeBetweenEvictionRuns(500) .minEvictableIdleTime(100) .numTestsPerEvictionRun(10) .addServer().host("localhost").port(hotRodServer.getPort()); remoteCacheManager = new RemoteCacheManager(clientBuilder.build()); remoteCache = remoteCacheManager.getCache(); TcpTransportFactory tcpConnectionFactory = (TcpTransportFactory) TestingUtil.extractField(remoteCacheManager, "transportFactory"); connectionPool = (GenericKeyedObjectPool<?, ?>) TestingUtil.extractField(tcpConnectionFactory, "connectionPool"); return cacheManager; } @AfterClass @Override protected void destroyAfterClass() { super.destroyAfterClass(); killRemoteCacheManager(remoteCacheManager); killServers(hotRodServer); } public void testHeavyLoad() throws InterruptedException, ExecutionException { List<WorkerThread> workers = new ArrayList<WorkerThread>(); //create 20 threads and do work with them for (int i =0; i < 20; i++) { WorkerThread workerThread = new WorkerThread(remoteCache); workers.add(workerThread); workerThread.stress(); } while (connectionPool.getNumActive() <= 15) { Thread.sleep(10); } for (WorkerThread wt: workers) { wt.stop(); } for (WorkerThread wt: workers) { wt.awaitTermination(); } //now wait for the idle thread to wake up and clean them eventually(new Condition() { @Override public boolean isSatisfied() throws Exception { int numIdle = connectionPool.getNumIdle(); int numActive = connectionPool.getNumActive(); return numIdle == 0 && numActive == 0; } }); } public static class ConstantDelayTransportInterceptor extends CommandInterceptor { private int millis; public ConstantDelayTransportInterceptor(int millis) { this.millis = millis; } @Override protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable { Thread.sleep(millis); return super.handleDefault(ctx, command); } } }