Urjit
Urjit

Reputation: 1190

How to gracefully stop Guava AbstractScheduledService using a shutdown hook?

I am using an AbstractScheduledService with a scheduler. A simple pattern like:

class MyService extends AbstractScheduledService {

   // KEEP THIS VAR IN MIND W.R.T the SHUTDOWN_HOOK BELOW
   public static volatile boolean keepRunning = true;

   protected void startUp() throws Exception {
     // startup stuff
   }

   protected void runOneIteration() throws Exception {
     // main logic stuff
   }

   protected void shutDown() throws Exception {
     // shutdown stuff
   }

   protected Scheduler scheduler() {
     return Scheduler.newFixedRateSchedule(0, 1, TimeUnit.SECONDS);
   }
 }

Now, I want to implement a typical shutdown hook like this: (the below snippet will be in main method)

final Thread mainThread = Thread.currentThread();
        LOGGER.debug("Adding the shutdown hook");
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                keepRunning = false;
                LOGGER.debug("The shutdown hook was engaged. Setting keepRunnning to false.");
                try {
                     // Is this appropriate?
                     mainThread.join();
                } catch (InterruptedException e) {
                    // handle exception here
                }
            }
        });

The shutdown hook is from typical docs example. It doesn't seem to work well with the Guava services pattern since the service itself is running on a different thread.

My service has a polling loop in the runOneIteration() logic. I want it to complete it's current task at hand and then shutdown gracefully when is sees that the keepRunning is now false since the Shutdown hook was engaged some time in the recent past when it was busy with its current iteration.

Any ideas how this can be done gracefully (complete current iteration and then shutdown)?

Upvotes: 4

Views: 3388

Answers (1)

Christofer
Christofer

Reputation: 61

Wouldn't you just call stopAndWait()?

Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            service.stopAsync().awaitTerminated(60, TimeUnit.SECONDS);
        }
});

Upvotes: 6

Related Questions