1

I am trying to add Graceful shut down in one of my server. I know the code is working. I was hoping that after redeployment of the server, first the graceful shutdown work and then the server would restart . But it is not happening. Can you all tell me the possibile reason's.

done := make(chan bool, 1)
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
    signal.Notify(quit, syscall.SIGHUP, syscall.SIGQUIT)
    signal.Notify(quit, syscall.SIGILL, syscall.SIGTRAP)
    signal.Notify(quit, syscall.SIGABRT, syscall.SIGBUS, syscall.SIGFPE)
    go func() {
        BootUpLog("before  <-quit")
        syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
        <-quit
        BootUpLog("shutting down")
        ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
        defer cancel()
        server.SetKeepAlivesEnabled(false)
        if err := server.Shutdown(ctx); err != nil {
            BootUpLog(fmt.Sprintf("Error in graceful shutdown of the server: %v", err))
        }
        close(done)
    }()
    if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
        BootUpLog(fmt.Sprintf("shut down with error: %v", err))
    }
    <-done
    BootUpLog("Shutdown gracefully.")
}

Here the log "before <-quit" is printing . And after redeploymet it is not receiving any signal in the <-quit channel.

1 Answers1

0

Could there be a problem with your BootUpLog() implementation? The following works for me (main.go):

package main

import (
    "context"
    "fmt"
    "html"
    "net/http"
    "os"
    "os/signal"
    "syscall"
)

func main() {
    fmt.Println("starting up")

    quit := make(chan os.Signal, 1)
    signal.Notify(quit, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
    signal.Notify(quit, syscall.SIGHUP, syscall.SIGQUIT)
    signal.Notify(quit, syscall.SIGILL, syscall.SIGTRAP)
    signal.Notify(quit, syscall.SIGABRT, syscall.SIGBUS, syscall.SIGFPE)

    server := &http.Server{
        Addr: ":8080",
    }
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
    })
    down := make(chan struct{})

    go func() {
        defer close(down)
        err := server.ListenAndServe()
        fmt.Println("shutting down: ", err)
    }()

    go func() {
        fmt.Println("before <- quit")
        syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
        fmt.Println("after signal sent")
        <-quit
        fmt.Println("after signal received")
        server.Shutdown(context.Background())
    }()

    <-down
}

Running it:

$ go run main.go
starting up
before <- quit
after signal sent
after signal received
shutting down:  http: Server closed
Tinkerer
  • 865
  • 7
  • 9