I have a small standalone application that configures the scheduler to terminate gracefully. With the following configuration:
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setWaitForTasksToCompleteOnShutdown(true);
scheduler.setAwaitTerminationSeconds(60);
return scheduler;
}
I can get it to gracefully terminate the scheduler, but only if I don't have any @Scheduled(cron = ) task. Once I have one of those, no matter what the scheduler will get stuck until timeout. I already tried configuring it also with an executor and do the shutdown/await manually and the effect is exactly the same.
These cron jobs are not even running. They are set to run at a fixed time during the night for example.
Spring version: 4.2.8.RELEASE
This will happen when the timeout reaches the end:
2017.07.28 01:44:56 [Thread-3] WARN Timed out while waiting for executor 'taskScheduler' to terminate
Any thoughts?
In the Spring Boot Document, they said that 'Each SpringApplication will register a shutdown hook with the JVM to ensure that the ApplicationContext is closed gracefully on exit. ' When I click ctrl+c on the shell command, the application can be shutdown gracefully.
The @EnableScheduling annotation is used to enable the scheduler for your application. This annotation should be added into the main Spring Boot application class file. @SpringBootApplication @EnableScheduling public class DemoApplication { public static void main(String[] args) { SpringApplication.
The schedulers do not start or stop. In the real world, it is necessary to stop and restart the scheduler without restarting the spring boot application. The ScheduledAnnotationBeanPostProcessor class allows you to programmatically start and stop the scheduler without having to restart the spring boot application.
Another way to stop the scheduler would be manually canceling its Future. In the cases with multiple scheduler tasks, then we can maintain the Future map inside of the custom scheduler pool but cancel the corresponding scheduled Future based on scheduler class.
Because by default the ScheduledThreadPoolExecutor will wait for all delayed scheduled tasks to finish executing, even if scheduled tasks aren't running at that time.
Try this below:
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler() {
private static final long serialVersionUID = -1L;
@Override
public void destroy() {
this.getScheduledThreadPoolExecutor().setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
super.destroy();
}
};
scheduler.setWaitForTasksToCompleteOnShutdown(true);
scheduler.setAwaitTerminationSeconds(60);
return scheduler;
}
Then the ScheduledThreadPoolExecutor will only wait for scheduled tasks which are currently running to finish executing.
Possible bug in that version of Spring? Refer to jira.spring.io/browse/SPR-15067
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With