graceful shutdown server with syg
nasa9084
Posted on March 10, 2018
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"))
}
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)
}
}
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
Then launch one more Terminal, and send a request:
$ curl localhost:8080
hello
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!
Posted on March 10, 2018
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 30, 2024
November 30, 2024