Skip to content

Instantly share code, notes, and snippets.

@instabledesign
Created November 5, 2019 16:33
Show Gist options
  • Save instabledesign/eb29323dd8ba4af3807fd35c6f61343e to your computer and use it in GitHub Desktop.
Save instabledesign/eb29323dd8ba4af3807fd35c6f61343e to your computer and use it in GitHub Desktop.
Gracefull shutdown with timeout
package main
import (
"context"
"fmt"
"net"
"net/http"
"os"
"os/signal"
"time"
)
func main() {
// create a mainContext representing main Life
mainContext := context.Background()
srv := http.Server{
// http net based on mainContext
BaseContext: func(_ net.Listener) context.Context {
return mainContext
},
}
// create chan to interact with os.Signal
signalChan := make(chan os.Signal, 1)
stopChan := make(chan struct{}, 1)
signal.Notify(signalChan, os.Interrupt)
stopping := false
go func() {
for {
select {
case <-stopChan:
signal.Stop(signalChan)
close(stopChan)
close(signalChan)
return
case <-signalChan:
if stopping {
fmt.Println("second stop signal receive, kill application")
os.Exit(130) // When received second signal we gonne to exit
}
fmt.Println("stop signal receive, gracefull stop begin")
stopping = true
// we set a gracefull timeout in order to kill application if gracefull reach timeout
ctx, _ := context.WithTimeout(mainContext, 10*time.Second)
err := srv.Shutdown(ctx)
if err != nil {
println(err)
}
fmt.Println("gracefull stop ended")
stopChan <- struct{}{}
}
}
}()
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
panic(err)
}
<- stopChan
fmt.Println("process end")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment