spring-boot-2.6.6
I want my @Async tasks to delay a shutdown.
application.properties:
server.shutdown=graceful
server.shutdown.grace-period=30s
spring.task.execution.shutdown.await-termination=true
@SpringBootApplication
@EnableAsync
public class AppConfiguration {
public static void main(String[] args) {
SpringApplication.run(AppConfiguration.class, args);
}
}
@Service
public class AsyncService {
private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
@Async
void runAsync() throws InterruptedException {
LOGGER.info("Starting async job...");
TimeUnit.MINUTES.sleep(5);
LOGGER.info("Async job finished.");
}
}
@RestController
public class MyController {
@Autowired(required = false)
private AsyncService async;
@GetMapping("/async")
public String async() throws InterruptedException {
LOGGER.info("Async servlet accessed");
async.runAsync();
return "Async process started in background. Please shut down the application now!";
}
}
-webflux:
2022-04-06 13:24:16.976 INFO 267878 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port 8080
2022-04-06 13:24:16.986 INFO 267878 --- [ main] AppConfiguration : Started AppConfiguration in 0.801 seconds (JVM running for 1.076)
2022-04-06 13:24:30.666 INFO 267878 --- [or-http-epoll-2] HelloServlet : Async servlet accessed
2022-04-06 13:24:30.668 INFO 267878 --- [ task-1] AsyncService : Starting async job...
Disconnected from the target VM, address: '127.0.0.1:36143', transport: 'socket'
2022-04-06 13:24:34.429 INFO 267878 --- [ionShutdownHook] o.s.b.w.embedded.netty.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete
2022-04-06 13:24:34.431 INFO 267878 --- [ netty-shutdown] o.s.b.w.embedded.netty.GracefulShutdown : Graceful shutdown complete
Process finished with exit code 130 (interrupted by signal 2: SIGINT)
Comment From: membersound
My bad, I thought that spring.task.execution.shutdown.await-termination-period would wait infinite until server.shutdown.grace-period catches in.
Setting spring.task.execution.shutdown.await-termination-period=30s fixes my problem.
Anyways I'm leaving this open, as this might be a good improvement for the docs that await-termination-period may not be unsed if await-termination=true is set?
Comment From: pruidong
For Spring Framework only, Spring Boot does auto-configuration.
~With @EnableAsync, it is recommended that you provide your own asynchronous executor, because @EnableAsync uses SimpleAsyncTaskExecutor by default to execute threads, SimpleAsyncTaskExecutor is a single-threaded thread pool that creates a new thread for each task, and SimpleAsyncTaskExecutor does not limit the number of threads by default. Some In this case, it may lead to memory overflow.~
~To implement your own asynchronous executor, please refer to: EnableAsync.java documentation (https://docs.spring.io/spring-framework/docs/current/javadoc-api/).~
Comment From: snicoll
@pruidong thank you for trying to help but that recommendation applies to Spring Framework. Spring Boot auto-configures a suitable TaskExecutor if none is provided so what you've described above does not apply.
Comment From: pruidong
@pruidong thank you for trying to help but that recommendation applies to Spring Framework. Spring Boot auto-configures a suitable
TaskExecutorif none is provided so what you've described above does not apply.
sorry. let me change the description.
Comment From: wilkinsona
I think the current naming of the two properties implies a stronger relationship between awaitTermination and awaitTerminationPeriod than there actually is. I wonder if we should rename the former to align more closely with setWaitForTasksToCompleteOnShutdown on ExecutorConfigurationSupport to which it is mapped.
Comment From: ThomazPassarelli
Hi there,
I've got a rename suggestion: spring.task.execution.shutdown.await-termination -> spring.task.execution.shutdown.wait-for-completion.. I find it more intuitive and also fits the naming style better as suggested in the title.
If you think this suggestion fits the criteria, could you assign the issue to me?
Comment From: wilkinsona
Thanks for the suggestion.
We generally try to align the names of our configuration properties with the names of the underlying properties that they configure. There are two such configuration properties here:
spring.task.execution.shutdown.await-terminationthat is mapped ontosetWaitForTasksToCompleteOnShutdownspring.task.execution.shutdown.await-termination-periodthat is mapped ontosetAwaitTerminationMillis
I think wait-for-completion fits quite nicely with that.
Something that we haven't yet considered in this issue are the changes, if any, that should be applied to TaskExecutorBuilder. It provides an intermediate layer between the configuration properties and the ThreadPoolTaskExecutor. awaitTermination on the builder should probably be renamed as well. With virtual threads coming in Java 21, I think it's also worth keeping in mind https://github.com/spring-projects/spring-boot/issues/35711.
In short, I'm not sure that we're ready to proceed here. It feels like we need to do some design work to figure out exactly what should change and how it should change. I'll update the issue's labels accordingly. We'll comment on the issue once that design work has been done. If you have any suggestions for the builder and related classes, they would be welcome.