Commit f7ed2447 by bergquist

wait for all sub routines to finish

simple solution for waiting for all go sub routines to
finish before closing Grafana. We would use errGroup
here as well but I dont like spreading context's all
over the place.

closes #10131
parent 0c5ef145
...@@ -95,7 +95,7 @@ func (hs *HttpServer) Start(ctx context.Context) error { ...@@ -95,7 +95,7 @@ func (hs *HttpServer) Start(ctx context.Context) error {
func (hs *HttpServer) Shutdown(ctx context.Context) error { func (hs *HttpServer) Shutdown(ctx context.Context) error {
err := hs.httpSrv.Shutdown(ctx) err := hs.httpSrv.Shutdown(ctx)
hs.log.Info("stopped http server") hs.log.Info("Stopped HTTP server")
return err return err
} }
......
...@@ -14,8 +14,8 @@ import ( ...@@ -14,8 +14,8 @@ import (
"net/http" "net/http"
_ "net/http/pprof" _ "net/http/pprof"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/metrics" "github.com/grafana/grafana/pkg/metrics"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
_ "github.com/grafana/grafana/pkg/services/alerting/conditions" _ "github.com/grafana/grafana/pkg/services/alerting/conditions"
...@@ -40,9 +40,6 @@ var homePath = flag.String("homepath", "", "path to grafana install/home path, d ...@@ -40,9 +40,6 @@ var homePath = flag.String("homepath", "", "path to grafana install/home path, d
var pidFile = flag.String("pidfile", "", "path to pid file") var pidFile = flag.String("pidfile", "", "path to pid file")
var exitChan = make(chan int) var exitChan = make(chan int)
func init() {
}
func main() { func main() {
v := flag.Bool("v", false, "prints current version and exits") v := flag.Bool("v", false, "prints current version and exits")
profile := flag.Bool("profile", false, "Turn on pprof profiling") profile := flag.Bool("profile", false, "Turn on pprof profiling")
...@@ -82,12 +79,28 @@ func main() { ...@@ -82,12 +79,28 @@ func main() {
setting.BuildStamp = buildstampInt64 setting.BuildStamp = buildstampInt64
metrics.M_Grafana_Version.WithLabelValues(version).Set(1) metrics.M_Grafana_Version.WithLabelValues(version).Set(1)
shutdownCompleted := make(chan int)
server := NewGrafanaServer() server := NewGrafanaServer()
server.Start()
go listenToSystemSignals(server, shutdownCompleted)
go func() {
code := 0
if err := server.Start(); err != nil {
log.Error2("Startup failed", "error", err)
code = 1
}
exitChan <- code
}()
code := <-shutdownCompleted
log.Info2("Grafana shutdown completed.", "code", code)
log.Close()
os.Exit(code)
} }
func listenToSystemSignals(server models.GrafanaServer) { func listenToSystemSignals(server *GrafanaServerImpl, shutdownCompleted chan int) {
signalChan := make(chan os.Signal, 1) signalChan := make(chan os.Signal, 1)
ignoreChan := make(chan os.Signal, 1) ignoreChan := make(chan os.Signal, 1)
code := 0 code := 0
...@@ -97,10 +110,12 @@ func listenToSystemSignals(server models.GrafanaServer) { ...@@ -97,10 +110,12 @@ func listenToSystemSignals(server models.GrafanaServer) {
select { select {
case sig := <-signalChan: case sig := <-signalChan:
// Stops trace if profiling has been enabled trace.Stop() // Stops trace if profiling has been enabled
trace.Stop()
server.Shutdown(0, fmt.Sprintf("system signal: %s", sig)) server.Shutdown(0, fmt.Sprintf("system signal: %s", sig))
shutdownCompleted <- 0
case code = <-exitChan: case code = <-exitChan:
trace.Stop() // Stops trace if profiling has been enabled
server.Shutdown(code, "startup error") server.Shutdown(code, "startup error")
shutdownCompleted <- code
} }
} }
...@@ -11,7 +11,6 @@ import ( ...@@ -11,7 +11,6 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
"github.com/grafana/grafana/pkg/services/provisioning" "github.com/grafana/grafana/pkg/services/provisioning"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
...@@ -20,7 +19,6 @@ import ( ...@@ -20,7 +19,6 @@ import (
"github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/login" "github.com/grafana/grafana/pkg/login"
"github.com/grafana/grafana/pkg/metrics" "github.com/grafana/grafana/pkg/metrics"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/cleanup" "github.com/grafana/grafana/pkg/services/cleanup"
...@@ -33,7 +31,7 @@ import ( ...@@ -33,7 +31,7 @@ import (
"github.com/grafana/grafana/pkg/tracing" "github.com/grafana/grafana/pkg/tracing"
) )
func NewGrafanaServer() models.GrafanaServer { func NewGrafanaServer() *GrafanaServerImpl {
rootCtx, shutdownFn := context.WithCancel(context.Background()) rootCtx, shutdownFn := context.WithCancel(context.Background())
childRoutines, childCtx := errgroup.WithContext(rootCtx) childRoutines, childCtx := errgroup.WithContext(rootCtx)
...@@ -54,9 +52,7 @@ type GrafanaServerImpl struct { ...@@ -54,9 +52,7 @@ type GrafanaServerImpl struct {
httpServer *api.HttpServer httpServer *api.HttpServer
} }
func (g *GrafanaServerImpl) Start() { func (g *GrafanaServerImpl) Start() error {
go listenToSystemSignals(g)
g.initLogging() g.initLogging()
g.writePIDFile() g.writePIDFile()
...@@ -69,16 +65,12 @@ func (g *GrafanaServerImpl) Start() { ...@@ -69,16 +65,12 @@ func (g *GrafanaServerImpl) Start() {
plugins.Init() plugins.Init()
if err := provisioning.Init(g.context, setting.HomePath, setting.Cfg); err != nil { if err := provisioning.Init(g.context, setting.HomePath, setting.Cfg); err != nil {
logger.Error("Failed to provision Grafana from config", "error", err) return fmt.Errorf("Failed to provision Grafana from config. error: %v", err)
g.Shutdown(1, "Startup failed")
return
} }
closer, err := tracing.Init(setting.Cfg) closer, err := tracing.Init(setting.Cfg)
if err != nil { if err != nil {
g.log.Error("Tracing settings is not valid", "error", err) return fmt.Errorf("Tracing settings is not valid. error: %v", err)
g.Shutdown(1, "Startup failed")
return
} }
defer closer.Close() defer closer.Close()
...@@ -93,13 +85,12 @@ func (g *GrafanaServerImpl) Start() { ...@@ -93,13 +85,12 @@ func (g *GrafanaServerImpl) Start() {
g.childRoutines.Go(func() error { return cleanUpService.Run(g.context) }) g.childRoutines.Go(func() error { return cleanUpService.Run(g.context) })
if err = notifications.Init(); err != nil { if err = notifications.Init(); err != nil {
g.log.Error("Notification service failed to initialize", "error", err) return fmt.Errorf("Notification service failed to initialize. error: %v", err)
g.Shutdown(1, "Startup failed")
return
} }
SendSystemdNotification("READY=1") sendSystemdNotification("READY=1")
g.startHttpServer()
return g.startHttpServer()
} }
func initSql() { func initSql() {
...@@ -123,16 +114,16 @@ func (g *GrafanaServerImpl) initLogging() { ...@@ -123,16 +114,16 @@ func (g *GrafanaServerImpl) initLogging() {
setting.LogConfigurationInfo() setting.LogConfigurationInfo()
} }
func (g *GrafanaServerImpl) startHttpServer() { func (g *GrafanaServerImpl) startHttpServer() error {
g.httpServer = api.NewHttpServer() g.httpServer = api.NewHttpServer()
err := g.httpServer.Start(g.context) err := g.httpServer.Start(g.context)
if err != nil { if err != nil {
g.log.Error("Fail to start server", "error", err) return fmt.Errorf("Fail to start server. error: %v", err)
g.Shutdown(1, "Startup failed")
return
} }
return nil
} }
func (g *GrafanaServerImpl) Shutdown(code int, reason string) { func (g *GrafanaServerImpl) Shutdown(code int, reason string) {
...@@ -145,10 +136,9 @@ func (g *GrafanaServerImpl) Shutdown(code int, reason string) { ...@@ -145,10 +136,9 @@ func (g *GrafanaServerImpl) Shutdown(code int, reason string) {
g.shutdownFn() g.shutdownFn()
err = g.childRoutines.Wait() err = g.childRoutines.Wait()
if err != nil && err != context.Canceled {
g.log.Info("Shutdown completed", "reason", err) g.log.Error("Server shutdown completed with an error", "error", err)
log.Close() }
os.Exit(code)
} }
func (g *GrafanaServerImpl) writePIDFile() { func (g *GrafanaServerImpl) writePIDFile() {
...@@ -173,7 +163,7 @@ func (g *GrafanaServerImpl) writePIDFile() { ...@@ -173,7 +163,7 @@ func (g *GrafanaServerImpl) writePIDFile() {
g.log.Info("Writing PID file", "path", *pidFile, "pid", pid) g.log.Info("Writing PID file", "path", *pidFile, "pid", pid)
} }
func SendSystemdNotification(state string) error { func sendSystemdNotification(state string) error {
notifySocket := os.Getenv("NOTIFY_SOCKET") notifySocket := os.Getenv("NOTIFY_SOCKET")
if notifySocket == "" { if notifySocket == "" {
......
package models
type GrafanaServer interface {
Start()
Shutdown(code int, reason string)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment