From 30c2ac172fac7407b9c96ad0f6224ea5cf7a7715 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Sun, 24 Sep 2023 07:26:48 -0500 Subject: [PATCH] plugins: standardize server API and errors --- plugins/cmd/chainlink-median/main.go | 2 +- plugins/cmd/chainlink-solana/main.go | 2 +- plugins/cmd/chainlink-starknet/main.go | 2 +- plugins/server.go | 69 +++++++++++++++++++------- 4 files changed, 53 insertions(+), 22 deletions(-) diff --git a/plugins/cmd/chainlink-median/main.go b/plugins/cmd/chainlink-median/main.go index 4d966548525..00836fa7c24 100644 --- a/plugins/cmd/chainlink-median/main.go +++ b/plugins/cmd/chainlink-median/main.go @@ -14,7 +14,7 @@ const ( ) func main() { - s := plugins.StartServer(loggerName) + s := plugins.MustNewStartedServer(loggerName) defer s.Stop() p := median.NewPlugin(s.Logger) diff --git a/plugins/cmd/chainlink-solana/main.go b/plugins/cmd/chainlink-solana/main.go index 132d7244fdf..ec30fa59f41 100644 --- a/plugins/cmd/chainlink-solana/main.go +++ b/plugins/cmd/chainlink-solana/main.go @@ -21,7 +21,7 @@ const ( ) func main() { - s := plugins.StartServer(loggerName) + s := plugins.MustNewStartedServer(loggerName) defer s.Stop() p := &pluginRelayer{Base: plugins.Base{Logger: s.Logger}} diff --git a/plugins/cmd/chainlink-starknet/main.go b/plugins/cmd/chainlink-starknet/main.go index aa69c85fe42..1052f3c1fc6 100644 --- a/plugins/cmd/chainlink-starknet/main.go +++ b/plugins/cmd/chainlink-starknet/main.go @@ -21,7 +21,7 @@ const ( ) func main() { - s := plugins.StartServer(loggerName) + s := plugins.MustNewStartedServer(loggerName) defer s.Stop() p := &pluginRelayer{Base: plugins.Base{Logger: s.Logger}} diff --git a/plugins/server.go b/plugins/server.go index 0d0e0dc62c4..b1d43612480 100644 --- a/plugins/server.go +++ b/plugins/server.go @@ -9,47 +9,78 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services" ) -// StartServer returns a started Server. +// NewStartedServer returns a started Server. // The caller is responsible for calling Server.Stop(). -func StartServer(loggerName string) *Server { - s := Server{ +func NewStartedServer(loggerName string) (*Server, error) { + s, err := newServer(loggerName) + if err != nil { + return nil, err + } + err = s.start() + if err != nil { + return nil, err + } + + return s, nil +} + +// MustNewStartedServer returns a new started Server like NewStartedServer, but logs and exits in the event of error. +// The caller is responsible for calling Server.Stop(). +func MustNewStartedServer(loggerName string) *Server { + s, err := newServer(loggerName) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to start server: %s\n", err) + os.Exit(1) + } + err = s.start() + if err != nil { + s.Logger.Fatalf("Failed to start server: %s", err) + } + + return s +} + +// Server holds common plugin server fields. +type Server struct { + loop.GRPCOpts + Logger logger.SugaredLogger + *PromServer + services.Checker +} + +func newServer(loggerName string) (*Server, error) { + s := &Server{ // default prometheus.Registerer GRPCOpts: loop.SetupTelemetry(nil), } lggr, err := loop.NewLogger() if err != nil { - fmt.Fprintf(os.Stderr, "Failed to create logger: %s\n", err) - os.Exit(1) + return nil, fmt.Errorf("error creating logger: %s", err) } lggr = logger.Named(lggr, loggerName) s.Logger = logger.Sugared(lggr) + return s, nil +} +func (s *Server) start() error { envCfg, err := GetEnvConfig() if err != nil { - lggr.Fatalf("Failed to get environment configuration: %s\n", err) + return fmt.Errorf("error getting environment configuration: %w", err) } - s.PromServer = NewPromServer(envCfg.PrometheusPort(), lggr) + s.PromServer = NewPromServer(envCfg.PrometheusPort(), s.lggr) err = s.PromServer.Start() if err != nil { - lggr.Fatalf("Unrecoverable error starting prometheus server: %s", err) + return fmt.Errorf("error starting prometheus server: %w", err) } s.Checker = services.NewChecker() err = s.Checker.Start() if err != nil { - lggr.Fatalf("Failed to start health checker: %v", err) + return fmt.Errorf("error starting health checker: %w", err) } - return &s -} - -// Server holds common plugin server fields. -type Server struct { - loop.GRPCOpts - Logger logger.SugaredLogger - *PromServer - services.Checker + return nil } // MustRegister registers the Checkable with services.Checker, or exits upon failure. @@ -62,7 +93,7 @@ func (s *Server) MustRegister(c services.Checkable) { // Stop closes resources and flushes logs. func (s *Server) Stop() { s.Logger.ErrorIfFn(s.Checker.Close, "Failed to close health checker") - s.Logger.ErrorIfFn(s.PromServer.Close, "error closing prometheus server") + s.Logger.ErrorIfFn(s.PromServer.Close, "Failed to close prometheus server") if err := s.Logger.Sync(); err != nil { fmt.Println("Failed to sync logger:", err) }