diff --git a/pkg/api/http_server.go b/pkg/api/http_server.go index b1024e2da9f..c1a3b238041 100644 --- a/pkg/api/http_server.go +++ b/pkg/api/http_server.go @@ -25,6 +25,8 @@ type HttpServer struct { macaron *macaron.Macaron context context.Context streamManager *live.StreamManager + + httpSrv *http.Server } func NewHttpServer() *HttpServer { @@ -46,11 +48,20 @@ func (hs *HttpServer) Start(ctx context.Context) error { listenAddr := fmt.Sprintf("%s:%s", setting.HttpAddr, setting.HttpPort) hs.log.Info("Initializing HTTP Server", "address", listenAddr, "protocol", setting.Protocol, "subUrl", setting.AppSubUrl) + hs.httpSrv = &http.Server{Addr: listenAddr, Handler: hs.macaron} switch setting.Protocol { case setting.HTTP: - err = http.ListenAndServe(listenAddr, hs.macaron) + err = hs.httpSrv.ListenAndServe() + if err == http.ErrServerClosed { + hs.log.Debug("server was shutdown gracefully") + return nil + } case setting.HTTPS: - err = hs.listenAndServeTLS(listenAddr, setting.CertFile, setting.KeyFile) + err = hs.httpSrv.ListenAndServeTLS(setting.CertFile, setting.KeyFile) + if err == http.ErrServerClosed { + hs.log.Debug("server was shutdown gracefully") + return nil + } default: hs.log.Error("Invalid protocol", "protocol", setting.Protocol) err = errors.New("Invalid Protocol") @@ -59,6 +70,12 @@ func (hs *HttpServer) Start(ctx context.Context) error { return err } +func (hs *HttpServer) Shutdown(ctx context.Context) error { + err := hs.httpSrv.Shutdown(ctx) + hs.log.Info("stopped http server") + return err +} + func (hs *HttpServer) listenAndServeTLS(listenAddr, certfile, keyfile string) error { if certfile == "" { return fmt.Errorf("cert_file cannot be empty when using HTTPS") diff --git a/pkg/cmd/grafana-server/server.go b/pkg/cmd/grafana-server/server.go index af8f79e9eda..30da2342c2b 100644 --- a/pkg/cmd/grafana-server/server.go +++ b/pkg/cmd/grafana-server/server.go @@ -3,7 +3,6 @@ package main import ( "context" "os" - "time" "golang.org/x/sync/errgroup" @@ -39,6 +38,8 @@ type GrafanaServerImpl struct { shutdownFn context.CancelFunc childRoutines *errgroup.Group log log.Logger + + httpServer *api.HttpServer } func (g *GrafanaServerImpl) Start() { @@ -74,9 +75,9 @@ func (g *GrafanaServerImpl) Start() { } func (g *GrafanaServerImpl) startHttpServer() { - httpServer := api.NewHttpServer() + g.httpServer = api.NewHttpServer() - err := httpServer.Start(g.context) + err := g.httpServer.Start(g.context) if err != nil { g.log.Error("Fail to start server", "error", err) @@ -88,8 +89,13 @@ func (g *GrafanaServerImpl) startHttpServer() { func (g *GrafanaServerImpl) Shutdown(code int, reason string) { g.log.Info("Shutdown started", "code", code, "reason", reason) + err := g.httpServer.Shutdown(g.context) + if err != nil { + g.log.Error("Failed to shutdown server", "error", err) + } + g.shutdownFn() - err := g.childRoutines.Wait() + err = g.childRoutines.Wait() g.log.Info("Shutdown completed", "reason", err) log.Close()