Support asynchronous launch of partitions.

Resolves #785

Updated to allow user to set ThreadPoolTaskExecutor.

updated based on code review
This commit is contained in:
Glenn Renfro
2022-02-23 17:31:59 -05:00
parent 362d73650b
commit 2a4a066f5f
9 changed files with 378 additions and 134 deletions

View File

@@ -30,4 +30,13 @@ NOTE: Since this example uses the Spring Cloud Deployer Local to launch the part
== Dependencies:
A datasource (not in memory) must be configured based on normal Spring Boot conventions
(application.properties/application.yml/environment variables/etc).
(application.properties, application.yml, environment variables).
== Asynchronous remote partition task launch
Currently partitions are launched sequentially. To launch them asynchronously set the following environment variables:
* `spring.cloud.task.closecontextEnabled=true`
* `io.spring.asynchronous=true`
NOTE: We need to close the context since the use of ThreadPoolTaskExecutor leaves a thread active thus the app will not terminate.
To close the application appropriately, we will need to set `spring.cloud.task.closecontextEnabled`` to true.

View File

@@ -20,7 +20,7 @@
<spring-cloud-commons.version>4.0.0-SNAPSHOT</spring-cloud-commons.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>17</java.version>
<spring-cloud-deployer>2.7.4</spring-cloud-deployer>
<spring-cloud-deployer>2.8.0-SNAPSHOT</spring-cloud-deployer>
</properties>
<dependencyManagement>

View File

@@ -40,6 +40,7 @@ import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.deployer.resource.support.DelegatingResourceLoader;
import org.springframework.cloud.deployer.spi.task.TaskLauncher;
import org.springframework.cloud.task.batch.partition.DeployerPartitionHandler;
@@ -53,6 +54,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
* @author Michael Minella
@@ -79,12 +81,14 @@ public class JobConfiguration {
private Environment environment;
@Bean
public PartitionHandler partitionHandler(TaskLauncher taskLauncher, JobExplorer jobExplorer, TaskRepository taskRepository) throws Exception {
public PartitionHandler partitionHandler(TaskLauncher taskLauncher, JobExplorer jobExplorer,
TaskRepository taskRepository, @Autowired(required = false) ThreadPoolTaskExecutor executor) throws Exception {
Resource resource = this.resourceLoader
.getResource("maven://io.spring.cloud:partitioned-batch-job:2.2.0.BUILD-SNAPSHOT");
.getResource("maven://io.spring.cloud:partitioned-batch-job:3.0.0-SNAPSHOT");
DeployerPartitionHandler partitionHandler =
new DeployerPartitionHandler(taskLauncher, jobExplorer, resource, "workerStep", taskRepository);
new DeployerPartitionHandler(taskLauncher, jobExplorer, resource,
"workerStep", taskRepository, executor);
List<String> commandLineArgs = new ArrayList<>(3);
commandLineArgs.add("--spring.profiles.active=worker");
@@ -100,6 +104,19 @@ public class JobConfiguration {
return partitionHandler;
}
@ConditionalOnProperty( value="io.spring.asynchronous",
havingValue = "true",
matchIfMissing = false)
@Bean
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setThreadNamePrefix("default_task_executor_thread");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.initialize();
return executor;
}
@Bean
public Partitioner partitioner() {
return new Partitioner() {