0

So the question is simple, but I cannot find an answer for quite a while now.

I have manual acknowledgement for my Kafka consumer, and before the application is shutdown I would like to execute some code and then acknowledge to Kafka. So for this I am using the @PreDestroy annotation:

@PreDestroy
private void beforeShutdown() {
    //do some code
    acknowledgement.acknowledge(); //this variable is stored on class level

Now the main problem is that Kafka consumer is shut down BEFORE this executes, therefor the messages don't actually get acknowledged and I receive them again when I start up the app, so I need some kind of workaround or another way to designate this function as the first thing that is called before shutdown. Proof of this can be seen in the log:

Shutting down ExecutorService
Consumer stopped
Shutting down ExecutorService 'taskScheduler'
Shutting down ExecutorService 'applicationTaskExecutor'
EXECUTING MY CODE
[Producer clientId=producer-1] Closing the Kafka producer with timeoutMillis = 30000 ms.

If anyone has a suggestion please tell.

Zim8662
  • 331
  • 2
  • 6

1 Answers1

1

Implement SmartLifeCycle and put the code in stop(). Put the bean in a very high Phase so it is stopped before the container. The containers are in phase Integer.MAX_VALUE - 100 by default so it has to be higher than that.

EDIT

class Listener implements SmartLifecycle { // default phase is last (after the containers for start, before for stop).

    private volatile boolean running;

    @Override
    public void start() {
        this.running = true;
    }

    @Override
    public void stop() {
        this.running = false;
    }

    @Override
    public boolean isRunning() {
        return this.running;
    }

    ...

}
Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Could you please provide an example of this? Seems like a good idea, I've read the docs for it now but am unsure how to change it's Phase? Btw in docs it says that default phase is Integer.MAX_VALUE and I see no Phase setter..? – Zim8662 Feb 14 '19 at 15:47
  • What doesn't have a setter? The phase is set on the connection factory bean. See the edit for an example. – Gary Russell Feb 14 '19 at 16:09