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 call server.Shutdown()
.
As pointing out this statement, I believe you're trying to shutdown gracefully by catching system event. Although things like os.Exit()
or panic
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 call server.Shutdown()
with context.
With current approaching, try this way:
func main() {
port := os.Getenv("PORT")
fmt.Printf("Started\n")
if port == "" {
port = "8080"
}
go func() {
http.HandleFunc("/", HelloServer)
if err := http.ListenAndServe(":"+port, nil); err != nil {
log.Fatal(err)
}
}()
signalChannel := make(chan os.Signal, 2)
signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM)
for {
sig := <-signalChannel
switch sig {
case os.Interrupt:
fmt.Println("sigint")
case syscall.SIGTERM:
fmt.Println("sigterm")
return
}
}
}
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. Kill go run
will just send the signal to it and the subprocess will be terminated. Let's try with go build
to see what happen exactly.