I have Spring Boot console app with scheduled by cron tasks. Scheduler expression obtained programmatically (can be JSON file or DB). There is a check for the scheduler expression and if it is not valid, it doesn't start scheduled task
Here is a code snippet:
@Service
public class DynamicScheduler implements SchedulingConfigurer {
private static final Logger _logger = LoggerFactory.getLogger(DynamicScheduler.class);
@Autowired
MyTask _myTask;
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(poolScheduler());
String triggerExpr = getExtressionFromExternal(); //From some source like JSON file or DB
if (canScheduleTask(triggerExpr)) {
taskRegistrar.addTriggerTask(() -> scheduleCron(triggerExpr), t -> {
CronTrigger crontrigger = new CronTrigger(triggerExpr);
return crontrigger.nextExecution(t);
});
}
else {
_logger.error("Cannot schedule execution");
}
}
private void scheduleCron(String cron) {
_myTask.run(); //execute code of the scheduled task
}
private boolean canScheduleTask(String triggerExpr) {
//Check if triggerExpr is valid
}
@Bean
public TaskScheduler poolScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setThreadNamePrefix("ThreadPoolTaskScheduler");
scheduler.setPoolSize(1);
scheduler.initialize();
return scheduler;
}
}
Currently, if the cron expression is not valid, it will be running with 0 tasks scheduled. Is it possible in this case to exit gracefully from the app or the only possible way to exit by throwing exception?
In Spring boot application, there are many ways to close the application. One such way of closing the application is via ConfigurableApplicationContext. This class object will help in shutting the spring boot application and after then System.exit(0) would help in cleaning the process. Below is the code which helps in stopping the application.
@Autowired
private ConfigurableApplicationContext ctx;
public void close() {
int staticExitCode = SpringApplication.exit(ctx, () -> 0);
System.exit(staticExitCode);
}
I would also suggest to cleanup other resources using @PreDestroy annotation on method and do the cleanup part.
@PreDestroy
public void cleanUp() {
// Clean up resources, close connections, etc.
System.out.println("Cleaning up resources before shutdown...");
}
Spring boot also provide 2 properties for graceful shutdown.
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=30s
Hope this would help.