From 411e8a16c2c07c1d934ba4c316cdfe076a1a7287 Mon Sep 17 00:00:00 2001 From: bergquist Date: Mon, 11 Dec 2017 15:05:06 +0100 Subject: [PATCH] backend plugins: manage plugins lifecycle with context --- pkg/cmd/grafana-server/server.go | 4 ++-- pkg/plugins/backend_datasource.go | 25 ++++++++------------ pkg/plugins/plugins.go | 38 +++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/pkg/cmd/grafana-server/server.go b/pkg/cmd/grafana-server/server.go index d7aad85fba0..dd14e33f26e 100644 --- a/pkg/cmd/grafana-server/server.go +++ b/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) diff --git a/pkg/plugins/backend_datasource.go b/pkg/plugins/backend_datasource.go index 9c6cb2f8687..51f1a118a14 100644 --- a/pkg/plugins/backend_datasource.go +++ b/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() { diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index a4a8f62d063..43b55d78b9f 100644 --- a/pkg/plugins/plugins.go +++ b/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 {