diff --git a/spring-statemachine-build-tests/src/test/java/org/springframework/statemachine/buildtests/TimerSmokeTests.java b/spring-statemachine-build-tests/src/test/java/org/springframework/statemachine/buildtests/TimerSmokeTests.java index 3245e79f1..91bb7d489 100644 --- a/spring-statemachine-build-tests/src/test/java/org/springframework/statemachine/buildtests/TimerSmokeTests.java +++ b/spring-statemachine-build-tests/src/test/java/org/springframework/statemachine/buildtests/TimerSmokeTests.java @@ -16,7 +16,10 @@ package org.springframework.statemachine.buildtests; import org.junit.Test; +import org.springframework.core.task.SyncTaskExecutor; +import org.springframework.core.task.TaskExecutor; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.statemachine.StateMachine; import org.springframework.statemachine.config.StateMachineBuilder; import org.springframework.statemachine.test.StateMachineTestPlan; @@ -25,8 +28,10 @@ public class TimerSmokeTests { private static ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); + private static ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); { taskExecutor.initialize(); + taskScheduler.initialize(); } private StateMachine buildMachine() throws Exception { @@ -35,7 +40,8 @@ private StateMachine buildMachine() throws Exception { builder.configureConfiguration() .withConfiguration() - .taskExecutor(taskExecutor); + .taskExecutor(taskExecutor) + .taskScheduler(taskScheduler); builder.configureStates() .withStates() diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/StateMachineSystemConstants.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/StateMachineSystemConstants.java index c812a624e..e437f7741 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/StateMachineSystemConstants.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/StateMachineSystemConstants.java @@ -38,4 +38,7 @@ public abstract class StateMachineSystemConstants { /** Bean name for task executor */ public static final String TASK_EXECUTOR_BEAN_NAME = "stateMachineTaskExecutor"; + /** Task scheduler threads prefix **/ + public static final String TASK_SCHEDULER_THREAD_PREFIX = "spring-state-machine-task-scheduler-"; + } diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/StateMachineBuilder.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/StateMachineBuilder.java index 258c055b9..3fded9c1c 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/StateMachineBuilder.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/StateMachineBuilder.java @@ -16,9 +16,10 @@ package org.springframework.statemachine.config; import org.springframework.core.task.SyncTaskExecutor; -import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.statemachine.StateMachine; import org.springframework.statemachine.StateMachineException; +import org.springframework.statemachine.StateMachineSystemConstants; import org.springframework.statemachine.config.builders.StateMachineConfigBuilder; import org.springframework.statemachine.config.builders.StateMachineConfigurationBuilder; import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer; @@ -35,6 +36,11 @@ import org.springframework.statemachine.config.model.ConfigurationData; import org.springframework.statemachine.config.model.StatesData; import org.springframework.statemachine.config.model.TransitionsData; +import org.springframework.statemachine.listener.StateMachineListener; +import org.springframework.statemachine.listener.StateMachineListenerAdapter; + +import java.util.ArrayList; +import java.util.Collection; /** * {@code StateMachineBuilder} provides a builder pattern for @@ -147,12 +153,35 @@ public StateMachine build() { } else { stateMachineFactory.setTaskExecutor(new SyncTaskExecutor()); } + + final Collection> resourceManagementListeners = new ArrayList<>(); if (stateMachineConfigurationConfig.getTaskScheduler() != null) { stateMachineFactory.setTaskScheduler(stateMachineConfigurationConfig.getTaskScheduler()); } else { - stateMachineFactory.setTaskScheduler(new ConcurrentTaskScheduler()); + final ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); + taskScheduler.setThreadNamePrefix(StateMachineSystemConstants.TASK_SCHEDULER_THREAD_PREFIX); + taskScheduler.setPoolSize(1); + taskScheduler.setWaitForTasksToCompleteOnShutdown(true); + taskScheduler.setAwaitTerminationSeconds(10); + taskScheduler.afterPropertiesSet(); + stateMachineFactory.setTaskScheduler(taskScheduler); + resourceManagementListeners.add(new StateMachineListenerAdapter() { + @Override + public void stateMachineStarted(final StateMachine stateMachine) { + taskScheduler.afterPropertiesSet(); + } + + @Override + public void stateMachineStopped(final StateMachine stateMachine) { + taskScheduler.destroy(); + } + }); + } + final StateMachine stateMachine = stateMachineFactory.getStateMachine(); + for (final StateMachineListener listener : resourceManagementListeners) { + stateMachine.addStateListener(listener); } - return stateMachineFactory.getStateMachine(); + return stateMachine; } catch (Exception e) { throw new StateMachineException("Error building state machine", e); } diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configuration/StateMachineCommonConfiguration.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configuration/StateMachineCommonConfiguration.java index f3c5a86a0..e1391bd2c 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configuration/StateMachineCommonConfiguration.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configuration/StateMachineCommonConfiguration.java @@ -20,7 +20,7 @@ import org.springframework.core.task.SyncTaskExecutor; import org.springframework.core.task.TaskExecutor; import org.springframework.scheduling.TaskScheduler; -import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.statemachine.StateMachineSystemConstants; /** @@ -39,7 +39,7 @@ public TaskExecutor taskExecutor() { @Bean public TaskScheduler taskScheduler() { - return new ConcurrentTaskScheduler(); + return new ThreadPoolTaskScheduler(); } @Bean(name = StateMachineHandlerApplicationListener.BEAN_NAME)