Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to process SIGTERM signal gracefully in Java?

Let's assume we have such a trivial daemon written in java:

public class Hellow {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        while(true) {
            // 1. do
            // 2. some
            // 3. important
            // 4. job
            // 5. sleep
        }

    }
}

and we daemonize it using start-stop-daemon which by default sends SIGTERM (TERM) signal on --stop

Let's suppose the current step performed is #2. And at this very moment we're sending TERM signal.

What happens is that the execution terminates immediately.

I've found that I can handle the signal event using addShutdownHook() but the thing is that it still interrupts the current execution and passes the control to handler:

public class Hellow {
    private static boolean shutdownFlag = false;
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        registerShutdownHook();

        try {
            doProcessing();
        } catch (InterruptedException ex) {
            System.out.println(ex);
        }
    }

    static private void doProcessing() throws InterruptedException {
        int i = 0;
        while(shutdownFlag == false) {
            i++;
            System.out.println("i:" + i);
            if(i == 5) {
                System.out.println("i is 5");
                System.exit(1); // for testing
            }

            System.out.println("Hello"); // It doesn't print after System.exit(1);

            Thread.sleep(1000);
        }
    }

    static public void setShutdownProcess() {
        shutdownFlag = true;
    }

    private static void registerShutdownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                System.out.println("Tralala");
                Hellow.setShutdownProcess();
            }
        });
    }
}

So, my question is - is it possible to not interrupt the current execution but handle the TERM signal in a separated thread (?) so that I would able to set shutdown_flag = True so that loop in main would had a chance to stop gracefully?

like image 695
Islomkhodja Hamidullakhodjaev Avatar asked Nov 18 '17 11:11

Islomkhodja Hamidullakhodjaev


People also ask

How does JVM handle SIGTERM?

The SIGTERM signal requests termination, whereby SIGKILL ...is sent to a process to cause it to terminate immediately... ...is executed for SIGTERM and SIGINT. The JVM executes the hook and waits, in the case above for 10 seconds, with the shutdown procedure until the completion of the shutdownHook .

How do you send a process in SIGTERM?

The command used to send a signal to a process is called kill. The kill command can send any specified signal to a process. If no signal is specified it sends the SIGTERM signal (hence the name "kill").

Can SIGTERM be handled?

The SIGTERM signal is a generic signal used to cause program termination. Unlike SIGKILL , this signal can be blocked, handled, and ignored. It is the normal way to politely ask a program to terminate.

What happens when a process receives SIGTERM?

If a process receives SIGTERM, some other process sent that signal. SIGTERM is the signal that is typically used to administratively terminate a process. That's not a signal that the kernel would send, but that's the signal a process would typically send to terminate (gracefully) another process.


1 Answers

I rewritten the registerShutdownHook() method and now it works as I wanted.

private static void registerShutdownHook() {
    final Thread mainThread = Thread.currentThread();
    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            try {
                System.out.println("Tralala");
                Hellow.setShutdownProcess();
                mainThread.join();
            } catch (InterruptedException ex) {
                System.out.println(ex);
            }

        }
    });  
}
like image 128
Islomkhodja Hamidullakhodjaev Avatar answered Oct 06 '22 13:10

Islomkhodja Hamidullakhodjaev