DEV Community

nasa9084
nasa9084

Posted on • Originally published at blog.web-apps.tech on

graceful shutdown server with syg

#go

originally posted to blob.web-apps.tech

Using github.com/nasa9084/syg, you can map signal to callback function easily.(c.f. syg: simply signal to callback mapping in Go)

Now, let's implement a HTTP server which shuts down gracefully when catch SIGINT.

package app

import (
    "context"
    "net/http"
    "os"
    "time"

    "github.com/nasa9084/syg"
)

type Server struct {
    server *http.Server
    closed chan struct{}
}

func NewServer() *Server {
    http.HandleFunc("/", longlongHandler)
    return &Server{
        server: &http.Server{
            Addr: ":8080",
        },
        closed: make(chan struct{}),
    }
}

func (s *Server) Run() error {
    // os.Interrupt = syscall.SIGINT
    cancel := syg.Listen(s.shutdown, os.Interrupt)
    defer cancel()

    err := s.server.ListenAndServe()
    <-s.closed
    return err
}

func (s *Server) shutdown(os.Signal) {
    s.Shutdown(context.Background())
    close(s.closed)
}

func longlongHandler(w http.ResponseWriter, r *http.Request) {
    // a very long process!
    time.Sleep(10 * time.Second)
    w.Write([]byte("hello"))
}
Enter fullscreen mode Exit fullscreen mode

call from main:

package main

import (
    "log"

    "foo/bar/app" // assume the app package above is in $GOPATH/foo/bar/app
)

func main() {
    s := app.NewServer()
    if err := s.Run(); err != http.ErrServerClosed {
        log.Print(err)
    }
}
Enter fullscreen mode Exit fullscreen mode

In main, you don't need to think goroutine, graceful shutdown, or signal listening.

Check the server is running well.

At first, build and run the server:

$ go build main.go
$ ./main

Enter fullscreen mode Exit fullscreen mode

Then launch one more Terminal, and send a request:

$ curl localhost:8080
hello
Enter fullscreen mode Exit fullscreen mode

after 10 seconds, message "hello" is returned.

Now, send request once again, type Ctrl-C(this means SIGINT) in the first terminal before returned the response.
The server will shut down after return the response, not suddenly.

We did it!

Oldest comments (0)