diff --git a/documentation/en/user/source/production/index.rst b/documentation/en/user/source/production/index.rst index 8d396d662..d2c4e358a 100644 --- a/documentation/en/user/source/production/index.rst +++ b/documentation/en/user/source/production/index.rst @@ -102,6 +102,33 @@ Resource Allocation Also see https://github.com/GeoWebCache/geowebcache/wiki/Estimating-the-number-of-tiles-and-size-on-disk for table that can be used to estimate how much storage you need and how long seeding will take +Seeder thread pool configuration +++++++++++++++++++++++++++++++ + +The number of concurrent seed tasks that GeoWebCache can execute is controlled by an internal +thread pool. You can configure its sizes using environment variables (values shown are +defaults used when variables are not set): + +- ``GWC_SEEDER_CORE_POOL_SIZE``: core pool size, defaults to ``16`` +- ``GWC_SEEDER_MAX_POOL_SIZE``: maximum pool size, defaults to ``32`` + +Example (Linux/macOS): + +.. code-block:: bash + + export GWC_SEEDER_CORE_POOL_SIZE=8 + export GWC_SEEDER_MAX_POOL_SIZE=16 + # start your servlet container / GeoWebCache here + +On Windows (PowerShell): + +.. code-block:: powershell + + $Env:GWC_SEEDER_CORE_POOL_SIZE = "8" + $Env:GWC_SEEDER_MAX_POOL_SIZE = "16" + # start your servlet container / GeoWebCache here + +These settings control the pool used to run seed tasks. Clustering ---------- diff --git a/geowebcache/core/src/test/java/org/geowebcache/seed/SeederThreadPoolExecutorConfigurationTest.java b/geowebcache/core/src/test/java/org/geowebcache/seed/SeederThreadPoolExecutorConfigurationTest.java new file mode 100644 index 000000000..8e9fb98b9 --- /dev/null +++ b/geowebcache/core/src/test/java/org/geowebcache/seed/SeederThreadPoolExecutorConfigurationTest.java @@ -0,0 +1,152 @@ +/** + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General + * Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + *

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + *

You should have received a copy of the GNU Lesser General Public License along with this program. If not, see + * . + */ +package org.geowebcache.seed; + +import static org.junit.Assert.assertEquals; + +import org.junit.After; +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.EnvironmentVariables; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * Test class to verify that the SeederThreadPoolExecutor configuration properly reads environment variables for core + * pool size and maximum pool size. + */ +public class SeederThreadPoolExecutorConfigurationTest { + + /** Allows to set environment variables for each individual test */ + @Rule + public final EnvironmentVariables environmentVariables = new EnvironmentVariables(); + + private ApplicationContext applicationContext; + + @After + public void tearDown() { + if (applicationContext != null) { + ((ClassPathXmlApplicationContext) applicationContext).close(); + } + } + + /** Test that default values are used when environment variables are not set. */ + @Test + public void testDefaultValuesWhenEnvironmentVariablesNotSet() { + // Clear any existing environment variables + environmentVariables.clear("GWC_SEEDER_CORE_POOL_SIZE"); + environmentVariables.clear("GWC_SEEDER_MAX_POOL_SIZE"); + + // Load the Spring context with test configuration + applicationContext = new ClassPathXmlApplicationContext("seeder-thread-pool-test-context.xml"); + + // Get the seeder thread pool executor bean + SeederThreadPoolExecutor executor = + applicationContext.getBean("gwcSeederThreadPoolExec", SeederThreadPoolExecutor.class); + + // Verify default values are used + assertEquals("Core pool size should default to 16", 16, executor.getCorePoolSize()); + assertEquals("Maximum pool size should default to 32", 32, executor.getMaximumPoolSize()); + + // Clean up + executor.shutdown(); + } + + /** Test that custom environment variable values are properly loaded. */ + @Test + public void testCustomEnvironmentVariableValues() { + // Set custom environment variables + environmentVariables.set("GWC_SEEDER_CORE_POOL_SIZE", "8"); + environmentVariables.set("GWC_SEEDER_MAX_POOL_SIZE", "16"); + + // Load the Spring context with test configuration + applicationContext = new ClassPathXmlApplicationContext("seeder-thread-pool-test-context.xml"); + + // Get the seeder thread pool executor bean + SeederThreadPoolExecutor executor = + applicationContext.getBean("gwcSeederThreadPoolExec", SeederThreadPoolExecutor.class); + + // Verify custom values are used + assertEquals("Core pool size should be set to 8", 8, executor.getCorePoolSize()); + assertEquals("Maximum pool size should be set to 16", 16, executor.getMaximumPoolSize()); + + // Clean up + executor.shutdown(); + } + + /** Test that only one environment variable is set (partial configuration). */ + @Test + public void testPartialEnvironmentVariableConfiguration() { + // Set only core pool size environment variable + environmentVariables.set("GWC_SEEDER_CORE_POOL_SIZE", "12"); + environmentVariables.clear("GWC_SEEDER_MAX_POOL_SIZE"); + + // Load the Spring context with test configuration + applicationContext = new ClassPathXmlApplicationContext("seeder-thread-pool-test-context.xml"); + + // Get the seeder thread pool executor bean + SeederThreadPoolExecutor executor = + applicationContext.getBean("gwcSeederThreadPoolExec", SeederThreadPoolExecutor.class); + + // Verify mixed configuration + assertEquals("Core pool size should be set to 12", 12, executor.getCorePoolSize()); + assertEquals("Maximum pool size should default to 32", 32, executor.getMaximumPoolSize()); + + // Clean up + executor.shutdown(); + } + + /** Test that invalid environment variable values fall back to defaults. */ + @Test + public void testInvalidEnvironmentVariableValues() { + // Set invalid environment variables + environmentVariables.set("GWC_SEEDER_CORE_POOL_SIZE", "invalid"); + environmentVariables.set("GWC_SEEDER_MAX_POOL_SIZE", "not_a_number"); + + // Load the Spring context with test configuration + applicationContext = new ClassPathXmlApplicationContext("seeder-thread-pool-test-context.xml"); + + // Get the seeder thread pool executor bean + SeederThreadPoolExecutor executor = + applicationContext.getBean("gwcSeederThreadPoolExec", SeederThreadPoolExecutor.class); + + // Verify default values are used when invalid values are provided + assertEquals("Core pool size should default to 16 when invalid value provided", 16, executor.getCorePoolSize()); + assertEquals( + "Maximum pool size should default to 32 when invalid value provided", + 32, + executor.getMaximumPoolSize()); + + // Clean up + executor.shutdown(); + } + + /** Test that the SeederThreadPoolExecutor can be created with various configurations. */ + @Test + public void testSeederThreadPoolExecutorCreation() { + // Test with different pool sizes + SeederThreadPoolExecutor executor1 = new SeederThreadPoolExecutor(4, 8); + assertEquals("Core pool size should be 4", 4, executor1.getCorePoolSize()); + assertEquals("Maximum pool size should be 8", 8, executor1.getMaximumPoolSize()); + executor1.shutdown(); + + SeederThreadPoolExecutor executor2 = new SeederThreadPoolExecutor(1, 1); + assertEquals("Core pool size should be 1", 1, executor2.getCorePoolSize()); + assertEquals("Maximum pool size should be 1", 1, executor2.getMaximumPoolSize()); + executor2.shutdown(); + + SeederThreadPoolExecutor executor3 = new SeederThreadPoolExecutor(64, 128); + assertEquals("Core pool size should be 64", 64, executor3.getCorePoolSize()); + assertEquals("Maximum pool size should be 128", 128, executor3.getMaximumPoolSize()); + executor3.shutdown(); + } +} diff --git a/geowebcache/core/src/test/resources/seeder-thread-pool-test-context.xml b/geowebcache/core/src/test/resources/seeder-thread-pool-test-context.xml new file mode 100644 index 000000000..f226d12e5 --- /dev/null +++ b/geowebcache/core/src/test/resources/seeder-thread-pool-test-context.xml @@ -0,0 +1,21 @@ + + + + + Test configuration for SeederThreadPoolExecutor with environment variables + + + + + + + + + + + + + + + diff --git a/geowebcache/web/src/main/webapp/WEB-INF/geowebcache-core-context.xml b/geowebcache/web/src/main/webapp/WEB-INF/geowebcache-core-context.xml index d1845c40f..107fc34f2 100644 --- a/geowebcache/web/src/main/webapp/WEB-INF/geowebcache-core-context.xml +++ b/geowebcache/web/src/main/webapp/WEB-INF/geowebcache-core-context.xml @@ -183,8 +183,8 @@ - - + +