DEV Community


Posted on • Originally published at on

graceful shutdown server with syg


originally posted to

Using, 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 (


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()
    return err

func (s *Server) shutdown(os.Signal) {

func longlongHandler(w http.ResponseWriter, r *http.Request) {
    // a very long process!
    time.Sleep(10 * time.Second)
Enter fullscreen mode Exit fullscreen mode

call from main:

package main

import (

    "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 {
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
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!

Top comments (0)