فهرست منبع

backend plugins: manage plugins lifecycle with context

bergquist 8 سال پیش
والد
کامیت
411e8a16c2
3فایلهای تغییر یافته به همراه37 افزوده شده و 30 حذف شده
  1. 2 2
      pkg/cmd/grafana-server/server.go
  2. 9 16
      pkg/plugins/backend_datasource.go
  3. 26 12
      pkg/plugins/plugins.go

+ 2 - 2
pkg/cmd/grafana-server/server.go

@@ -63,11 +63,11 @@ func (g *GrafanaServerImpl) Start() error {
 	login.Init()
 	social.NewOAuthService()
 
-	pluginCloser, err := plugins.Init()
+	pluginManager, err := plugins.NewPluginManager()
 	if err != nil {
 		return fmt.Errorf("Failed to start plugins. error: %v", err)
 	}
-	defer pluginCloser()
+	g.childRoutines.Go(func() error { return pluginManager.Run(g.context) })
 
 	if err := provisioning.Init(g.context, setting.HomePath, setting.Cfg); err != nil {
 		return fmt.Errorf("Failed to provision Grafana from config. error: %v", err)

+ 9 - 16
pkg/plugins/backend_datasource.go

@@ -20,19 +20,12 @@ type BackendDatasource struct {
 	*PluginBase
 
 	Executable string
+	log        log.Logger
 	client     *plugin.Client
 }
 
-type Killable interface {
-	Kill()
-}
-
-type NoopKiller struct{}
-
-func (nk NoopKiller) Kill() {}
-
-func (p *BackendDatasource) initBackendPlugin() (Killable, error) {
-	logger := log.New("grafana.plugins")
+func (p *BackendDatasource) initBackendPlugin(log log.Logger) error {
+	p.log = log.New("plugin-id", p.Id)
 
 	p.client = plugin.NewClient(&plugin.ClientConfig{
 		HandshakeConfig: plugin.HandshakeConfig{
@@ -43,33 +36,33 @@ func (p *BackendDatasource) initBackendPlugin() (Killable, error) {
 		Plugins:          map[string]plugin.Plugin{p.Id: &shared.TsdbPluginImpl{}},
 		Cmd:              exec.Command("sh", "-c", path.Join(p.PluginDir, p.Executable)),
 		AllowedProtocols: []plugin.Protocol{plugin.ProtocolGRPC},
-		Logger:           backend.LogWrapper{Logger: logger},
+		Logger:           backend.LogWrapper{Logger: p.log},
 	})
 
 	rpcClient, err := p.client.Client()
 	if err != nil {
-		return NoopKiller{}, err
+		return err
 	}
 
 	raw, err := rpcClient.Dispense(p.Id)
 	if err != nil {
-		return NoopKiller{}, err
+		return err
 	}
 
 	plugin := raw.(shared.TsdbPlugin)
 	response, err := plugin.Query(context.Background(), &proto.TsdbQuery{})
 
 	if err != nil {
-		logger.Error("Response from plugin. ", "response", response)
+		p.log.Error("Response from plugin. ", "response", response)
 	} else {
-		logger.Info("Response from plugin. ", "response", response)
+		p.log.Info("Response from plugin. ", "response", response)
 	}
 
 	tsdb.RegisterTsdbQueryEndpoint(p.Id, func(dsInfo *models.DataSource) (tsdb.TsdbQueryEndpoint, error) {
 		return &shared.TsdbWrapper{TsdbPlugin: plugin}, nil
 	})
 
-	return p.client, nil
+	return nil
 }
 
 func (p *BackendDatasource) Kill() {

+ 26 - 12
pkg/plugins/plugins.go

@@ -1,6 +1,7 @@
 package plugins
 
 import (
+	"context"
 	"encoding/json"
 	"errors"
 	"fmt"
@@ -37,7 +38,29 @@ type PluginScanner struct {
 
 type Dispose func()
 
-func Init() (Dispose, error) {
+type PluginManager struct {
+	log log.Logger
+}
+
+func NewPluginManager() (*PluginManager, error) {
+	Init()
+	return &PluginManager{
+		log: log.New("plugins"),
+	}, nil
+}
+
+func (p *PluginManager) Run(ctx context.Context) error {
+	<-ctx.Done()
+
+	for _, p := range BackendDatasources {
+		p.Kill()
+	}
+
+	p.log.Info("Stopped Plugins", "error", ctx.Err())
+	return ctx.Err()
+}
+
+func Init() error {
 	plog = log.New("plugins")
 
 	DataSources = make(map[string]*DataSourcePlugin)
@@ -82,26 +105,17 @@ func Init() (Dispose, error) {
 		app.initApp()
 	}
 
-	killers := []Killable{}
 	for _, be := range BackendDatasources {
-		killable, err := be.initBackendPlugin()
+		err := be.initBackendPlugin(plog)
 		if err != nil {
 			plog.Error("failed to init plugin", "id", be.Id, "error", err)
-		} else {
-			killers = append(killers, killable)
 		}
 	}
 
 	go StartPluginUpdateChecker()
 	go updateAppDashboards()
 
-	return dispose, nil
-}
-
-func dispose() {
-	for _, p := range BackendDatasources {
-		p.Kill()
-	}
+	return nil
 }
 
 func checkPluginPaths() error {