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")
}