Tymur Berezhnoi
Tymur Berezhnoi

Reputation: 706

Spring boot actuator shutdown doesn't terminate infinite loop

Im my spring boot application I have a component with a method that run some job in the infinite loop below, actually it checks some data in db:

while(true) {// DOES SOME JOB}

here is my app entry point for spring boot app:

@SpringBootApplication
public class Application implements CommandLineRunner {

    private final Service service;

    @Autowired
    public Application(Service service) {
        this.service = service;
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) {
        service.run();
    }
}

and I enabled actuator's shutdown endpoint, so I would kill the app via:curl -X POST localhost:8080/actuator/shutdown and in my case it kills only spring context but the loop still run... Is it possible to kill the whole app like System.exit(0) does (even with infinite loop).

NOTE: I know it's possible to write my own context aware endpoint with shutdown link and whenever some one request the endpoint I can close the spring context and Syste.exit(0) (it will definitely terminate the llop) and even provide boolean flag to the infinite loop, but does the spring provide something by default, let's say more elegant?

Upvotes: 0

Views: 2071

Answers (2)

Mark Bramnik
Mark Bramnik

Reputation: 42441

As for the actuator, its "shutdown" method closes the application context.

Although the bean is managed by spring but since there is an infinite loop in some of its methods, spring can't really know this and can't really break this loop.

Spring does manage the life-cycle of the beans and indeed like @Shruti Gupta has stated, you can create a method annotated with @PreDestroy annotation so that spring will call it, but then again, you must implement the logic of breaking the loop.

Here is an example of something that might work for you:

@Component
public class MyBean {
    private boolean shouldKeepCheckingDB = true; // consider volatile as well if you need it, kind of out of scope for this question, but might be useful

    public void checkDB() {
        while(shouldKeepCheckingDB) { // instead of while(true)
            // check the database
        }
    }

    @PreDestroy
    void stop() {
        this.shouldKeepCheckingDB = false;
    } 
}

Upvotes: 1

Shruti Gupta
Shruti Gupta

Reputation: 308

You can gracefully shutdown your application using @PreDestroy annotation

@PreDestroy
public void destroy() {
 System.out.println("destroy");
}

So, when you use ctrl+C to kill your application, the loop will also be killed.

Upvotes: 1

Related Questions