As per spring documentation for setWaitForTasksToCompleteOnShutdown
Set whether to wait for scheduled tasks to complete on shutdown
Does it mean that if any task is stuck on some long running process and we explicity try to stop the container, it will not be terminated untill that task is finished?
@Bean public TaskExecutor myAsyncTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(20); executor.setMaxPoolSize(30); executor.setQueueCapacity(50); executor.setWaitForTasksToCompleteOnShutdown(true); // How it behaves? //executor.afterPropertiesSet(); executor.setThreadNamePrefix("MY-ASYNC-TASK"); executor.initialize(); return executor; }
Thanks for the answers.
Advertisement
Answer
Short answer? Yes
On shutdown ( either by hitting by a request to the shutdown end point or by calling applicationcontext.close ) by default, Spring’s TaskExecutor simply interrupts all running tasks.
Note that your threads must be in an interruptible state (e.g. sleep) to actually be interrupted.
In some cases you may want to wait for all running tasks to be complete.
calling setWaitForTasksToCompleteOnShutdown(true) simply prevents interrupting the running tasks on shutdown and ensures that both the currently executing tasks and queued up tasks are completed.
( I assume this is because they are non-daemon threads that prevent application exit. )
In short, the answer to your question is yes.
You can play with the following piece of code. When you change setWait from false to true, you will see that the application will not exit until the sleep is over. When you set it to false, the application will terminate immediately.
import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.core.task.TaskExecutor; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @SpringBootApplication public class Application { @Autowired private TaskExecutor taskExecutor; @Bean public TaskExecutor taskExecutor() { ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); taskExecutor.setCorePoolSize(2); taskExecutor.setMaxPoolSize(2); taskExecutor.setWaitForTasksToCompleteOnShutdown(false); taskExecutor.initialize(); return taskExecutor; } @PostConstruct public void runTaskOnStartup() { for (int i = 0; i < 1; i++) { taskExecutor.execute(() -> { try { Thread.sleep(10_000); } catch (InterruptedException e) { System.out.println("Sleep Interrupted!"); e.printStackTrace(); } }); } } public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(Application.class, args); run.close(); } }