logo

Lucas Katayama/Graceful Server Stop

Created Sun, 29 Mar 2020 10:37:26 -0300 Modified Sun, 29 Mar 2020 10:37:26 -0300
128 Words

This is a piece of code that I use almost every time.

package main

import (
	"context"
	"fmt"
	log "github.com/sirupsen/logrus"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func router() http.Handler {
	return http.DefaultServeMux
}

func Run(host, port string) {
	srv := http.Server{
		Addr:    fmt.Sprintf("%s:%s", host, port),
		Handler: router(),
	}

	done := make(chan os.Signal, 1)
	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		
		log.Info("server started")
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("server error: %v", err)
		}
	
	}()
	
	<-done

	log.Info("shutdown server started")
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)

	if err := srv.Shutdown(ctx); err != nil {
		log.Errorf("server shutdown failed: %+v", err)
	}

	log.Info("server exited")	

	log.Info("shutting down other things")

	// Shutdown databases
	// Shutdown message brokers
	// ...

	cancel()
}

func main() {
	Run("localhost", "5000")
}

References