From ff814aec261dedce063df98055163d7dfdc2a251 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Tue, 9 Feb 2021 17:57:51 +0300 Subject: [PATCH] [#316] ir: Add before-start and after-stop function to Server Keep list of functions which are called first when the server starts (method Server.Start). If any of the starters returns an error, the server will not start. Such starters will mainly be used for resources that need to be initialized after a successful server construction, but before its main work (e.g. local files). Keep list of functions which are called when the server stops (Server.Stop method). Such closers will mainly be used for resources that need to be released after server shutdown (e.g. initialized by starters). Signed-off-by: Leonard Lyubich --- pkg/innerring/innerring.go | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go index 69900557..08b5936e 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -3,6 +3,7 @@ package innerring import ( "context" "crypto/ecdsa" + "io" "github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" @@ -62,6 +63,23 @@ type ( predefinedValidators []keys.PublicKey workers []func(context.Context) + + // Set of local resources that must be + // initialized at the very beginning of + // Server's work, (e.g. opening files). + // + // If any starter returns an error, Server's + // starting fails immediately. + starters []func() error + + // Set of local resources that must be + // released at Server's work completion + // (e.g closing files). + // + // Closer's wrong outcome shouldn't be critical. + // + // Errors are logged. + closers []func() error } contracts struct { @@ -93,6 +111,12 @@ const ( // Start runs all event providers. func (s *Server) Start(ctx context.Context, intError chan<- error) error { + for _, starter := range s.starters { + if err := starter(); err != nil { + return err + } + } + err := s.initConfigFromBlockchain() if err != nil { return err @@ -152,6 +176,26 @@ func (s *Server) startWorkers(ctx context.Context) { func (s *Server) Stop() { go s.morphListener.Stop() go s.mainnetListener.Stop() + + for _, c := range s.closers { + if err := c(); err != nil { + s.log.Warn("closer error", + zap.String("error", err.Error()), + ) + } + } +} + +func (s *Server) registerIOCloser(c io.Closer) { + s.registerCloser(c.Close) +} + +func (s *Server) registerCloser(f func() error) { + s.closers = append(s.closers, f) +} + +func (s *Server) registerStarter(f func() error) { + s.starters = append(s.starters, f) } // New creates instance of inner ring sever structure.