public void testScalingExecutorType() throws InterruptedException { String threadPoolName = randomThreadPool(ThreadPool.ThreadPoolType.SCALING); ThreadPool threadPool = null; try { Settings nodeSettings = Settings.builder() .put("threadpool." + threadPoolName + ".size", 10) .put("node.name", "testScalingExecutorType") .build(); threadPool = new ThreadPool(nodeSettings); ClusterSettings clusterSettings = new ClusterSettings(nodeSettings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); threadPool.setClusterSettings(clusterSettings); final int expectedMinimum = "generic".equals(threadPoolName) ? 4 : 1; assertThat(info(threadPool, threadPoolName).getMin(), equalTo(expectedMinimum)); assertThat(info(threadPool, threadPoolName).getMax(), equalTo(10)); final long expectedKeepAlive = "generic".equals(threadPoolName) ? 30 : 300; assertThat( info(threadPool, threadPoolName).getKeepAlive().seconds(), equalTo(expectedKeepAlive)); assertEquals( info(threadPool, threadPoolName).getThreadPoolType(), ThreadPool.ThreadPoolType.SCALING); assertThat(threadPool.executor(threadPoolName), instanceOf(EsThreadPoolExecutor.class)); // Change settings that doesn't require pool replacement Executor oldExecutor = threadPool.executor(threadPoolName); clusterSettings.applySettings( Settings.builder() .put("threadpool." + threadPoolName + ".keep_alive", "10m") .put("threadpool." + threadPoolName + ".min", "2") .put("threadpool." + threadPoolName + ".size", "15") .build()); assertEquals( info(threadPool, threadPoolName).getThreadPoolType(), ThreadPool.ThreadPoolType.SCALING); assertThat(threadPool.executor(threadPoolName), instanceOf(EsThreadPoolExecutor.class)); assertThat( ((EsThreadPoolExecutor) threadPool.executor(threadPoolName)).getCorePoolSize(), equalTo(2)); assertThat( ((EsThreadPoolExecutor) threadPool.executor(threadPoolName)).getMaximumPoolSize(), equalTo(15)); assertThat(info(threadPool, threadPoolName).getMin(), equalTo(2)); assertThat(info(threadPool, threadPoolName).getMax(), equalTo(15)); // Make sure keep alive value changed assertThat(info(threadPool, threadPoolName).getKeepAlive().minutes(), equalTo(10L)); assertThat( ((EsThreadPoolExecutor) threadPool.executor(threadPoolName)) .getKeepAliveTime(TimeUnit.MINUTES), equalTo(10L)); assertThat(threadPool.executor(threadPoolName), sameInstance(oldExecutor)); } finally { terminateThreadPoolIfNeeded(threadPool); } }
public void testIndexingThreadPoolsMaxSize() throws InterruptedException { String threadPoolName = randomThreadPoolName(); for (String name : new String[] {ThreadPool.Names.BULK, ThreadPool.Names.INDEX}) { ThreadPool threadPool = null; try { int maxSize = EsExecutors.boundedNumberOfProcessors(Settings.EMPTY); // try to create a too-big (maxSize+1) thread pool threadPool = new ThreadPool( Settings.builder() .put("node.name", "testIndexingThreadPoolsMaxSize") .put("threadpool." + name + ".size", maxSize + 1) .build()); // confirm it clipped us at the maxSize: assertEquals( maxSize, ((ThreadPoolExecutor) threadPool.executor(name)).getMaximumPoolSize()); ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); threadPool.setClusterSettings(clusterSettings); // update it to a tiny size: clusterSettings.applySettings( Settings.builder().put("threadpool." + name + ".size", 1).build()); // confirm it worked: assertEquals(1, ((ThreadPoolExecutor) threadPool.executor(name)).getMaximumPoolSize()); // try to update to too-big size: clusterSettings.applySettings( Settings.builder().put("threadpool." + name + ".size", maxSize + 1).build()); // confirm it clipped us at the maxSize: assertEquals( maxSize, ((ThreadPoolExecutor) threadPool.executor(name)).getMaximumPoolSize()); } finally { terminateThreadPoolIfNeeded(threadPool); } } }
public void testUpdateSettingsCanNotChangeThreadPoolType() throws InterruptedException { String threadPoolName = randomThreadPoolName(); ThreadPool.ThreadPoolType invalidThreadPoolType = randomIncorrectThreadPoolType(threadPoolName); ThreadPool.ThreadPoolType validThreadPoolType = ThreadPool.THREAD_POOL_TYPES.get(threadPoolName); ThreadPool threadPool = null; try { threadPool = new ThreadPool( Settings.builder() .put("node.name", "testUpdateSettingsCanNotChangeThreadPoolType") .build()); ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); threadPool.setClusterSettings(clusterSettings); clusterSettings.applySettings( Settings.builder() .put("threadpool." + threadPoolName + ".type", invalidThreadPoolType.getType()) .build()); fail("expected IllegalArgumentException"); } catch (IllegalArgumentException e) { assertEquals( "illegal value can't update [threadpool.] from [{}] to [{" + threadPoolName + ".type=" + invalidThreadPoolType.getType() + "}]", e.getMessage()); assertThat( e.getCause().getMessage(), is( "setting threadpool." + threadPoolName + ".type to " + invalidThreadPoolType.getType() + " is not permitted; must be " + validThreadPoolType.getType())); } finally { terminateThreadPoolIfNeeded(threadPool); } }
public void testShutdownNowInterrupts() throws Exception { String threadPoolName = randomThreadPool(ThreadPool.ThreadPoolType.FIXED); ThreadPool threadPool = null; try { Settings nodeSettings = Settings.builder() .put("threadpool." + threadPoolName + ".queue_size", 1000) .put("node.name", "testShutdownNowInterrupts") .build(); threadPool = new ThreadPool(nodeSettings); ClusterSettings clusterSettings = new ClusterSettings(nodeSettings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); threadPool.setClusterSettings(clusterSettings); assertEquals(info(threadPool, threadPoolName).getQueueSize().getSingles(), 1000L); final CountDownLatch latch = new CountDownLatch(1); ThreadPoolExecutor oldExecutor = (ThreadPoolExecutor) threadPool.executor(threadPoolName); threadPool .executor(threadPoolName) .execute( () -> { try { new CountDownLatch(1).await(); } catch (InterruptedException ex) { latch.countDown(); Thread.currentThread().interrupt(); } }); clusterSettings.applySettings( Settings.builder().put("threadpool." + threadPoolName + ".queue_size", 2000).build()); assertThat(threadPool.executor(threadPoolName), not(sameInstance(oldExecutor))); assertThat(oldExecutor.isShutdown(), equalTo(true)); assertThat(oldExecutor.isTerminating(), equalTo(true)); assertThat(oldExecutor.isTerminated(), equalTo(false)); threadPool.shutdownNow(); // should interrupt the thread latch.await( 3, TimeUnit.SECONDS); // If this throws then ThreadPool#shutdownNow didn't interrupt } finally { terminateThreadPoolIfNeeded(threadPool); } }
public void testCustomThreadPool() throws Exception { ThreadPool threadPool = null; try { Settings nodeSettings = Settings.builder() .put("threadpool.my_pool1.type", "scaling") .put("threadpool.my_pool1.min", 1) .put( "threadpool.my_pool1.size", EsExecutors.boundedNumberOfProcessors(Settings.EMPTY)) .put("threadpool.my_pool1.keep_alive", "1m") .put("threadpool.my_pool2.type", "fixed") .put("threadpool.my_pool2.size", "1") .put("threadpool.my_pool2.queue_size", "1") .put("node.name", "testCustomThreadPool") .build(); threadPool = new ThreadPool(nodeSettings); ClusterSettings clusterSettings = new ClusterSettings(nodeSettings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); threadPool.setClusterSettings(clusterSettings); ThreadPoolInfo groups = threadPool.info(); boolean foundPool1 = false; boolean foundPool2 = false; outer: for (ThreadPool.Info info : groups) { if ("my_pool1".equals(info.getName())) { foundPool1 = true; assertEquals(info.getThreadPoolType(), ThreadPool.ThreadPoolType.SCALING); } else if ("my_pool2".equals(info.getName())) { foundPool2 = true; assertEquals(info.getThreadPoolType(), ThreadPool.ThreadPoolType.FIXED); assertThat(info.getMin(), equalTo(1)); assertThat(info.getMax(), equalTo(1)); assertThat(info.getQueueSize().singles(), equalTo(1L)); } else { for (Field field : Names.class.getFields()) { if (info.getName().equalsIgnoreCase(field.getName())) { // This is ok it is a default thread pool continue outer; } } fail("Unexpected pool name: " + info.getName()); } } assertThat(foundPool1, is(true)); assertThat(foundPool2, is(true)); // Updating my_pool2 Settings settings = Settings.builder().put("threadpool.my_pool2.size", "10").build(); clusterSettings.applySettings(settings); groups = threadPool.info(); foundPool1 = false; foundPool2 = false; outer: for (ThreadPool.Info info : groups) { if ("my_pool1".equals(info.getName())) { foundPool1 = true; assertEquals(info.getThreadPoolType(), ThreadPool.ThreadPoolType.SCALING); } else if ("my_pool2".equals(info.getName())) { foundPool2 = true; assertThat(info.getMax(), equalTo(10)); assertThat(info.getMin(), equalTo(10)); assertThat(info.getQueueSize().singles(), equalTo(1L)); assertEquals(info.getThreadPoolType(), ThreadPool.ThreadPoolType.FIXED); } else { for (Field field : Names.class.getFields()) { if (info.getName().equalsIgnoreCase(field.getName())) { // This is ok it is a default thread pool continue outer; } } fail("Unexpected pool name: " + info.getName()); } } assertThat(foundPool1, is(true)); assertThat(foundPool2, is(true)); } finally { terminateThreadPoolIfNeeded(threadPool); } }
public void testFixedExecutorType() throws InterruptedException { String threadPoolName = randomThreadPool(ThreadPool.ThreadPoolType.FIXED); ThreadPool threadPool = null; try { Settings nodeSettings = Settings.builder().put("node.name", "testFixedExecutorType").build(); threadPool = new ThreadPool(nodeSettings); ClusterSettings clusterSettings = new ClusterSettings(nodeSettings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS); threadPool.setClusterSettings(clusterSettings); assertThat(threadPool.executor(threadPoolName), instanceOf(EsThreadPoolExecutor.class)); Settings settings = clusterSettings.applySettings( Settings.builder().put("threadpool." + threadPoolName + ".size", "15").build()); int expectedSize = getExpectedThreadPoolSize(nodeSettings, threadPoolName, 15); assertEquals( info(threadPool, threadPoolName).getThreadPoolType(), ThreadPool.ThreadPoolType.FIXED); assertThat(threadPool.executor(threadPoolName), instanceOf(EsThreadPoolExecutor.class)); assertThat( ((EsThreadPoolExecutor) threadPool.executor(threadPoolName)).getCorePoolSize(), equalTo(expectedSize)); assertThat( ((EsThreadPoolExecutor) threadPool.executor(threadPoolName)).getMaximumPoolSize(), equalTo(expectedSize)); assertThat(info(threadPool, threadPoolName).getMin(), equalTo(expectedSize)); assertThat(info(threadPool, threadPoolName).getMax(), equalTo(expectedSize)); // keep alive does not apply to fixed thread pools assertThat( ((EsThreadPoolExecutor) threadPool.executor(threadPoolName)) .getKeepAliveTime(TimeUnit.MINUTES), equalTo(0L)); // Put old type back settings = clusterSettings.applySettings(Settings.EMPTY); assertEquals( info(threadPool, threadPoolName).getThreadPoolType(), ThreadPool.ThreadPoolType.FIXED); // Make sure keep alive value is not used assertThat(info(threadPool, threadPoolName).getKeepAlive(), nullValue()); // Make sure keep pool size value were reused assertThat(info(threadPool, threadPoolName).getMin(), equalTo(expectedSize)); assertThat(info(threadPool, threadPoolName).getMax(), equalTo(expectedSize)); assertThat(threadPool.executor(threadPoolName), instanceOf(EsThreadPoolExecutor.class)); assertThat( ((EsThreadPoolExecutor) threadPool.executor(threadPoolName)).getCorePoolSize(), equalTo(expectedSize)); assertThat( ((EsThreadPoolExecutor) threadPool.executor(threadPoolName)).getMaximumPoolSize(), equalTo(expectedSize)); // Change size Executor oldExecutor = threadPool.executor(threadPoolName); settings = clusterSettings.applySettings( Settings.builder() .put(settings) .put("threadpool." + threadPoolName + ".size", "10") .build()); expectedSize = getExpectedThreadPoolSize(nodeSettings, threadPoolName, 10); // Make sure size values changed assertThat(info(threadPool, threadPoolName).getMax(), equalTo(expectedSize)); assertThat(info(threadPool, threadPoolName).getMin(), equalTo(expectedSize)); assertThat( ((EsThreadPoolExecutor) threadPool.executor(threadPoolName)).getMaximumPoolSize(), equalTo(expectedSize)); assertThat( ((EsThreadPoolExecutor) threadPool.executor(threadPoolName)).getCorePoolSize(), equalTo(expectedSize)); // Make sure executor didn't change assertEquals( info(threadPool, threadPoolName).getThreadPoolType(), ThreadPool.ThreadPoolType.FIXED); assertThat(threadPool.executor(threadPoolName), sameInstance(oldExecutor)); // Change queue capacity clusterSettings.applySettings( Settings.builder() .put(settings) .put("threadpool." + threadPoolName + ".queue", "500") .build()); } finally { terminateThreadPoolIfNeeded(threadPool); } }