Description
Steps to reproduce:
- Create a minimal spring-boot 3.2.2 project
- Add @EnableScheduling to application
- Define a taskScheduler bean of type ThreadPoolTaskScheduler
- Create a method annotated with
@Scheduled(fixedRate=1000)
- Have a long running process in that method
- In application.properties set
server.shutdown=graceful
andspring.lifecycle.timeout-per-shutdown-phase=5s
If I understand the docs correctly, the long running process should be canceled immediately and the task scheduler should be destroyed.
However, when signaling the application to shutdown, the long running process is not aborted immediately. Instead, I get an error message after 5 seconds: Failed to shut down 1 bean with phase value 2147483647 within timeout of 5000ms: [taskScheduler]
If I configure the taskScheduler with
taskScheduler.setWaitForTasksToCompleteOnShutdown(true);
taskScheduler.setAwaitTerminationMillis(0);
the task is canceled immediately.
Minimal example
@Bean
public TaskScheduler taskScheduler() {
var taskScheduler = new ThreadPoolTaskScheduler() {
@Override
public void destroy() {
log.info("taskScheduler Destroy");
super.destroy();
}
};
taskScheduler.setPoolSize(10);
taskScheduler.setWaitForTasksToCompleteOnShutdown(false); // this doesn't result in task cancelation.
// taskScheduler.setWaitForTasksToCompleteOnShutdown(true);
// taskScheduler.setAwaitTerminationMillis(0); // this results result in immediate task cancelation
return taskScheduler;
}
@Scheduled(fixedRate = 1000)
public void scheduled() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
@PreDestroy
void predestroy() {
log.info("predestroy");
}
The TaskScheduler's destroy method and the predestroy() method are not called until after the 5 second timeout.
If I configure the taskScheduler with setWaitForTasksToCompleteOnShutdown(true) and taskScheduler.setAwaitTerminationMillis(0), these methods are called immediately.
Is there a misunderstanding on my part, an error in the docs, or a bug?