Browse Source

refactor(main): refactoring main grafana server / startup code

Torkel Ödegaard 9 years ago
parent
commit
86b546c21d
3 changed files with 138 additions and 63 deletions
  1. 6 60
      pkg/cmd/grafana-server/main.go
  2. 129 0
      pkg/cmd/grafana-server/server.go
  3. 3 3
      pkg/models/server.go

+ 6 - 60
pkg/cmd/grafana-server/main.go

@@ -1,7 +1,6 @@
 package main
 
 import (
-	"context"
 	"flag"
 	"fmt"
 	"io/ioutil"
@@ -13,21 +12,11 @@ import (
 	"syscall"
 	"time"
 
-	"golang.org/x/sync/errgroup"
-
 	"github.com/grafana/grafana/pkg/log"
-	"github.com/grafana/grafana/pkg/login"
-	"github.com/grafana/grafana/pkg/metrics"
-	"github.com/grafana/grafana/pkg/plugins"
-	"github.com/grafana/grafana/pkg/services/cleanup"
-	"github.com/grafana/grafana/pkg/services/eventpublisher"
-	"github.com/grafana/grafana/pkg/services/notifications"
-	"github.com/grafana/grafana/pkg/services/search"
+	"github.com/grafana/grafana/pkg/models"
 	"github.com/grafana/grafana/pkg/services/sqlstore"
 	"github.com/grafana/grafana/pkg/setting"
-	"github.com/grafana/grafana/pkg/social"
 
-	"github.com/grafana/grafana/pkg/services/alerting"
 	_ "github.com/grafana/grafana/pkg/services/alerting/conditions"
 	_ "github.com/grafana/grafana/pkg/services/alerting/notifiers"
 	_ "github.com/grafana/grafana/pkg/tsdb/graphite"
@@ -66,41 +55,8 @@ func main() {
 	setting.BuildCommit = commit
 	setting.BuildStamp = buildstampInt64
 
-	appContext, shutdownFn := context.WithCancel(context.Background())
-	grafanaGroup, appContext := errgroup.WithContext(appContext)
-
-	go listenToSystemSignals(shutdownFn, grafanaGroup)
-
-	flag.Parse()
-	writePIDFile()
-
-	initRuntime()
-	initSql()
-	metrics.Init()
-	search.Init()
-	login.Init()
-	social.NewOAuthService()
-	eventpublisher.Init()
-	plugins.Init()
-
-	// init alerting
-	if setting.AlertingEnabled {
-		engine := alerting.NewEngine()
-		grafanaGroup.Go(func() error { return engine.Run(appContext) })
-	}
-
-	// cleanup service
-	cleanUpService := cleanup.NewCleanUpService()
-	grafanaGroup.Go(func() error { return cleanUpService.Run(appContext) })
-
-	if err := notifications.Init(); err != nil {
-		log.Fatal(3, "Notification service failed to initialize", err)
-	}
-
-	exitCode := StartServer()
-
-	grafanaGroup.Wait()
-	exitChan <- exitCode
+	server := NewGrafanaServer()
+	server.Start()
 }
 
 func initRuntime() {
@@ -143,7 +99,7 @@ func writePIDFile() {
 	}
 }
 
-func listenToSystemSignals(cancel context.CancelFunc, grafanaGroup *errgroup.Group) {
+func listenToSystemSignals(server models.GrafanaServer) {
 	signalChan := make(chan os.Signal, 1)
 	code := 0
 
@@ -151,18 +107,8 @@ func listenToSystemSignals(cancel context.CancelFunc, grafanaGroup *errgroup.Gro
 
 	select {
 	case sig := <-signalChan:
-		log.Info2("Received system signal. Shutting down", "signal", sig)
+		server.Shutdown(0, fmt.Sprintf("system signal=%s", sig))
 	case code = <-exitChan:
-		switch code {
-		case 0:
-			log.Info("Shutting down")
-		default:
-			log.Warn("Shutting down")
-		}
+		server.Shutdown(code, "startup error")
 	}
-
-	cancel()
-	grafanaGroup.Wait()
-	log.Close()
-	os.Exit(code)
 }

+ 129 - 0
pkg/cmd/grafana-server/server.go

@@ -0,0 +1,129 @@
+package main
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"os"
+	"time"
+
+	"golang.org/x/sync/errgroup"
+
+	"github.com/grafana/grafana/pkg/api"
+	"github.com/grafana/grafana/pkg/log"
+	"github.com/grafana/grafana/pkg/login"
+	"github.com/grafana/grafana/pkg/metrics"
+	"github.com/grafana/grafana/pkg/models"
+	"github.com/grafana/grafana/pkg/plugins"
+	"github.com/grafana/grafana/pkg/services/alerting"
+	"github.com/grafana/grafana/pkg/services/cleanup"
+	"github.com/grafana/grafana/pkg/services/eventpublisher"
+	"github.com/grafana/grafana/pkg/services/notifications"
+	"github.com/grafana/grafana/pkg/services/search"
+	"github.com/grafana/grafana/pkg/setting"
+	"github.com/grafana/grafana/pkg/social"
+)
+
+func NewGrafanaServer() models.GrafanaServer {
+	rootCtx, shutdownFn := context.WithCancel(context.Background())
+	childRoutines, childCtx := errgroup.WithContext(rootCtx)
+
+	return &GrafanaServerImpl{
+		context:       childCtx,
+		shutdownFn:    shutdownFn,
+		childRoutines: childRoutines,
+		log:           log.New("server"),
+	}
+}
+
+type GrafanaServerImpl struct {
+	context       context.Context
+	shutdownFn    context.CancelFunc
+	childRoutines *errgroup.Group
+	log           log.Logger
+}
+
+func (g *GrafanaServerImpl) Start() {
+	go listenToSystemSignals(g)
+
+	writePIDFile()
+	initRuntime()
+	initSql()
+	metrics.Init()
+	search.Init()
+	login.Init()
+	social.NewOAuthService()
+	eventpublisher.Init()
+	plugins.Init()
+
+	// init alerting
+	if setting.AlertingEnabled {
+		engine := alerting.NewEngine()
+		g.childRoutines.Go(func() error { return engine.Run(g.context) })
+	}
+
+	// cleanup service
+	cleanUpService := cleanup.NewCleanUpService()
+	g.childRoutines.Go(func() error { return cleanUpService.Run(g.context) })
+
+	if err := notifications.Init(); err != nil {
+		g.log.Error("Notification service failed to initialize", "erro", err)
+		g.Shutdown(1, "Startup failed")
+		return
+	}
+
+	g.startHttpServer()
+}
+
+func (g *GrafanaServerImpl) startHttpServer() {
+	logger = log.New("http.server")
+
+	var err error
+	m := newMacaron()
+	api.Register(m)
+
+	listenAddr := fmt.Sprintf("%s:%s", setting.HttpAddr, setting.HttpPort)
+	g.log.Info("Initializing HTTP Server", "address", listenAddr, "protocol", setting.Protocol, "subUrl", setting.AppSubUrl)
+
+	switch setting.Protocol {
+	case setting.HTTP:
+		err = http.ListenAndServe(listenAddr, m)
+	case setting.HTTPS:
+		err = http.ListenAndServeTLS(listenAddr, setting.CertFile, setting.KeyFile, m)
+	default:
+		g.log.Error("Invalid protocol", "protocol", setting.Protocol)
+		g.Shutdown(1, "Startup failed")
+	}
+
+	if err != nil {
+		g.log.Error("Fail to start server", "error", err)
+		g.Shutdown(1, "Startup failed")
+		return
+	}
+}
+
+func (g *GrafanaServerImpl) Shutdown(code int, reason string) {
+	log.Info("Shutting down", "code", code, "reason", reason)
+
+	g.shutdownFn()
+	err := g.childRoutines.Wait()
+
+	log.Info("Shutting down completed", "error", err)
+
+	log.Close()
+	os.Exit(code)
+}
+
+// implement context.Context
+func (g *GrafanaServerImpl) Deadline() (deadline time.Time, ok bool) {
+	return g.context.Deadline()
+}
+func (g *GrafanaServerImpl) Done() <-chan struct{} {
+	return g.context.Done()
+}
+func (g *GrafanaServerImpl) Err() error {
+	return g.context.Err()
+}
+func (g *GrafanaServerImpl) Value(key interface{}) interface{} {
+	return g.context.Value(key)
+}

+ 3 - 3
pkg/core/core.go → pkg/models/server.go

@@ -1,10 +1,10 @@
-package core
+package models
 
 import "context"
 
 type GrafanaServer interface {
 	context.Context
-}
 
-type GrafanaServerImpl struct {
+	Start()
+	Shutdown(code int, reason string)
 }