I'm having trouble quitting my main.go app when the SIGTERM event is triggered.
The SIGTERM case in the switch statement doesn't get called and the "triggered" is not printed out.
Here is my code
func main() {
port := os.Getenv("PORT")
fmt.Printf("Started\n")
if port == "" {
port = "8080"
}
signalChannel := make(chan os.Signal, 2)
signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM)
go func() {
sig := <-signalChannel
switch sig {
case os.Interrupt:
//nothing yet
case syscall.SIGTERM:
fmt.Printf("triggered") //never gets called
}
}()
http.HandleFunc("/", HelloServer)
http.ListenAndServe(":" + port, nil)
}
I've tried the following solution but can't get it to work.
Because the
http.ListenAndServe()
is running on the main goroutine. It will lock the process to serve the http server.So no matter what you do inside another goroutine, it doesn't take effect, except you can try to kill that server. To do that, you must get the reference to the server to callserver.Shutdown()
.As pointing out this statement, I believe you're trying to shutdown gracefully by catching system event. Although things like
os.Exit()
orpanic
can do the job but it's a bad practice when http.Server is running. It'd be better to keep a reference to the running server to callserver.Shutdown()
with context.With current approaching, try this way:
Updated:
A common reason that fmt.Println("sigterm") doesn't show up is that executing by
go run
, because the process is running in a subprocess. Killgo run
will just send the signal to it and the subprocess will be terminated. Let's try withgo build
to see what happen exactly.