7

Is it possible to catch a sigterm in Golang and move on on the code, like a panic/defer?

Example:

func main() {
    fmt.Println("app started")
    setupGracefulShutdown()

    for {
    }
    close()    
}

func close() {
    fmt.Println("infinite loop stopped and got here")
}

func setupGracefulShutdown() {
    sigChan := make(chan os.Signal)
    signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)

    go func() {
        fmt.Println(" got interrupt signal: ", <-sigChan)
    }()
}

// "app started"
// CTRL + C
// ^C "got interrupt signal:  interrupt"
// app don't stop

What I want is to print infinite loop stopped and got here and finish application.

// "app started"
// CTRL + C
// ^C "got interrupt signal:  interrupt"
// "infinite loop stopped and got here"
phuclv
  • 37,963
  • 15
  • 156
  • 475
Cae Vecchi
  • 868
  • 1
  • 10
  • 19
  • 2
    Your "infinite" loop could monitor the `sigChan` and "break" once a value is received from it. What's wrong with that? – icza Jun 24 '19 at 10:57
  • Side note: make a chan with cap 1 for your signals. – Volker Jun 24 '19 at 11:08
  • 1
    The example is for visualisation only, I have no control over the infinite loop, I'm trying to implement this on an internal library. – Cae Vecchi Jun 24 '19 at 12:16

1 Answers1

12

This is very easy to achieve. Because the signal channel needs to block and wait for a signal, you have to start your business logic code in a different goroutine.

func main() {
    cancelChan := make(chan os.Signal, 1)
    // catch SIGETRM or SIGINTERRUPT
    signal.Notify(cancelChan, syscall.SIGTERM, syscall.SIGINT)
    go func() {
        // start your software here. Maybe your need to replace the for loop with other code
        for {
            // replace the time.Sleep with your code
            log.Println("Loop tick")
            time.Sleep(time.Second)
        }
    }()
    sig := <-cancelChan
    log.Printf("Caught signal %v", sig)
    // shutdown other goroutines gracefully
    // close other resources
}
rfay
  • 9,963
  • 1
  • 47
  • 89
georgeok
  • 5,321
  • 2
  • 39
  • 61