diff --git a/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/AbstractFunctionalTest.java b/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/AbstractFunctionalTest.java
index a92f004ca..89de98454 100644
--- a/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/AbstractFunctionalTest.java
+++ b/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/AbstractFunctionalTest.java
@@ -17,6 +17,8 @@
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
@@ -34,6 +36,7 @@
public abstract class AbstractFunctionalTest extends BasicJavaClientREST {
protected final static String DB_NAME = "java-functest";
+ protected final Logger logger = LoggerFactory.getLogger(getClass());
protected final static ObjectMapper objectMapper = new ObjectMapper();
diff --git a/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/datamovement/AdjustQueryBatcherThreadCountTest.java b/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/datamovement/AdjustQueryBatcherThreadCountTest.java
new file mode 100644
index 000000000..3ce0c9c9b
--- /dev/null
+++ b/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/datamovement/AdjustQueryBatcherThreadCountTest.java
@@ -0,0 +1,132 @@
+package com.marklogic.client.fastfunctest.datamovement;
+
+import com.marklogic.client.datamovement.DataMovementManager;
+import com.marklogic.client.datamovement.QueryBatcher;
+import com.marklogic.client.fastfunctest.AbstractFunctionalTest;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class AdjustQueryBatcherThreadCountTest extends AbstractFunctionalTest {
+
+ @Test
+ void increaseThreadCount() {
+ List
This method cannot be called after the job has started.
+ *Unless otherwise noted by a subclass, this method cannot be called after the job has started.
* * @param threadCount the number of threads to use in this Batcher * diff --git a/marklogic-client-api/src/main/java/com/marklogic/client/datamovement/QueryBatcher.java b/marklogic-client-api/src/main/java/com/marklogic/client/datamovement/QueryBatcher.java index db9ade49e..d273b9db7 100644 --- a/marklogic-client-api/src/main/java/com/marklogic/client/datamovement/QueryBatcher.java +++ b/marklogic-client-api/src/main/java/com/marklogic/client/datamovement/QueryBatcher.java @@ -142,7 +142,7 @@ public interface QueryBatcher extends Batcher { QueryBatcher onQueryFailure(QueryFailureListener listener); /** - *Add a listener to run when the Query job is completed i.e. when all the + *
Add a listener to run when the Query job is completed i.e. when all the * document URIs are retrieved and the associated listeners are completed
* * @param listener the code to run when the Query job is completed @@ -333,6 +333,12 @@ public interface QueryBatcher extends Batcher { * threads used for processing the queued batches (running processEvent on * the listeners regiested with onUrisReady). * + * As of the 6.2.0 release, this can now be adjusted after the batcher has been started. The underlying Java + * {@code ThreadPoolExecutor} will have both its core and max pool sizes set to the given thread count. Use caution + * when reducing this to a value of 1 while the batcher is running; in some cases, the underlying + * {@code ThreadPoolExecutor} may halt execution of any tasks. Execution can be resumed by increasing the thread count + * to a value of 2 or higher. + * * @return this instance for method chaining */ @Override @@ -391,19 +397,19 @@ public interface QueryBatcher extends Batcher { * Retry in the same thread to query a batch that failed. If it fails again, * all the failure listeners associated with the batcher using onQueryFailure * method would be processed. - * + * * Note : Use this method with caution as there is a possibility of infinite * loops. If a batch fails and one of the failure listeners calls this method * to retry with failure listeners and if the batch again fails, this would go * on as an infinite loop until the batch succeeds. - * + * * @param queryEvent the information about the batch that failed */ void retryWithFailureListeners(QueryEvent queryEvent); - + /** * Sets the limit for the maximum number of batches that can be collected. - * + * * @param maxBatches is the value of the limit. */ void setMaxBatches(long maxBatches); @@ -412,10 +418,10 @@ public interface QueryBatcher extends Batcher { * Caps the query at the current batch. */ void setMaxBatches(); - + /** - * Returns the maximum number of Batches for the current job. - * + * Returns the maximum number of Batches for the current job. + * * @return the maximum number of Batches that can be collected. */ long getMaxBatches(); diff --git a/marklogic-client-api/src/main/java/com/marklogic/client/datamovement/impl/QueryBatcherImpl.java b/marklogic-client-api/src/main/java/com/marklogic/client/datamovement/impl/QueryBatcherImpl.java index 13d086d17..e565e3e9c 100644 --- a/marklogic-client-api/src/main/java/com/marklogic/client/datamovement/impl/QueryBatcherImpl.java +++ b/marklogic-client-api/src/main/java/com/marklogic/client/datamovement/impl/QueryBatcherImpl.java @@ -364,12 +364,17 @@ public int getMaxDocToUriBatchRatio() { @Override public QueryBatcher withThreadCount(int threadCount) { - requireNotStarted(); - if ( getThreadCount() <= 0 ) { + if (threadCount <= 0 ) { throw new IllegalArgumentException("threadCount must be 1 or greater"); } - threadCountSet = true; - super.withThreadCount(threadCount); + if (threadPool != null) { + logger.info("Adjusting thread pool size from {} to {}", getThreadCount(), threadCount); + threadPool.setCorePoolSize(threadCount); + threadPool.setMaximumPoolSize(threadCount); + } else { + threadCountSet = true; + } + super.withThreadCount(threadCount); return this; }