Skip to content

Instantly share code, notes, and snippets.

@gocs
Last active July 17, 2022 02:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gocs/689c2763487868988019bc54ee9dc8ef to your computer and use it in GitHub Desktop.
Save gocs/689c2763487868988019bc54ee9dc8ef to your computer and use it in GitHub Desktop.
signal cancel and timeout on an infinite loop go golang

golang program to gracefully terminate on SIGTERM signal or timeout in a loop

ctrl + c gracefully terminates the app using the current terminal

terminate app from different terminal

the program output its pid

...
pid: <pid>

executing the ff command will terminate the program

$ kill -15 <pid>

waiting for 25 seconds terminates the app by itself

you can still test your app within its duration

curl localhost:8080
# Hello World! 2022-07-17 ...
package main
import (
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
func greet(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World! %s", time.Now())
}
func main() {
// cancel
c := make(chan os.Signal)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
endSignal := make(chan struct{})
go func() {
fmt.Println("pid:", os.Getpid())
<-c
fmt.Println("terminating..")
endSignal <- struct{}{}
}()
// timeout
hr, err := time.ParseDuration("25s")
if err != nil {
fmt.Println("err parse duration:", err)
return
}
timeout := time.After(hr)
pollInt := 5 * time.Second
// app
go func() {
http.HandleFunc("/", greet)
http.ListenAndServe(":8080", nil)
}()
count := time.Duration(0)
for {
select {
case <-endSignal:
fmt.Println("The end!")
return
case <-timeout:
fmt.Println("Time's up!")
return
default:
}
time.Sleep(pollInt)
count += pollInt
fmt.Println("time remaining:", hr-count)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment