refactor code for context fallthrough

This commit is contained in:
Lawrence, Rendall
2022-11-01 17:02:24 +03:00
parent d6de38bdbd
commit d8d6f2cf4b
22 changed files with 312 additions and 493 deletions

View File

@@ -37,7 +37,7 @@ func main() {
if err := s.Run(*configPath); err != nil {
log.Fatal("unable to start server: ", err)
}
defer s.Dispose()
defer s.Shutdown()
ch := make(chan os.Signal, 2)
signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
<-ch

View File

@@ -3,20 +3,23 @@ package main
import (
"errors"
"fmt"
"io"
"sync"
"github.com/rs/zerolog"
"github.com/sot-tech/mochi/frontend"
"github.com/sot-tech/mochi/middleware"
"github.com/sot-tech/mochi/pkg/log"
"github.com/sot-tech/mochi/pkg/metrics"
"github.com/sot-tech/mochi/pkg/stop"
"github.com/sot-tech/mochi/storage"
)
// Server represents the state of a running instance.
type Server struct {
storage storage.PeerStorage
logic *middleware.Logic
sg *stop.Group
frontends []io.Closer
hooks []io.Closer
storage storage.PeerStorage
}
// Run begins an instance of Conf.
@@ -28,11 +31,9 @@ func (r *Server) Run(configFilePath string) error {
return fmt.Errorf("failed to read config: %w", err)
}
r.sg = stop.NewGroup()
if len(cfg.MetricsAddr) > 0 {
log.Info().Str("address", cfg.MetricsAddr).Msg("starting metrics server")
r.sg.Add(metrics.NewServer(cfg.MetricsAddr))
r.frontends = append(r.frontends, metrics.NewServer(cfg.MetricsAddr))
} else {
log.Info().Msg("metrics disabled because of empty address")
}
@@ -46,17 +47,30 @@ func (r *Server) Run(configFilePath string) error {
if err != nil {
return fmt.Errorf("failed to configure pre-hooks: %w", err)
}
for _, h := range preHooks {
if c, isOk := h.(io.Closer); isOk {
r.hooks = append(r.hooks, c)
}
}
postHooks, err := middleware.NewHooks(cfg.PostHooks, r.storage)
if err != nil {
return fmt.Errorf("failed to configure post-hooks: %w", err)
}
for _, h := range postHooks {
if c, isOk := h.(io.Closer); isOk {
r.hooks = append(r.hooks, c)
}
}
if len(cfg.Frontends) > 0 {
var fs []frontend.Frontend
r.logic = middleware.NewLogic(cfg.AnnounceInterval, cfg.MinAnnounceInterval, r.storage, preHooks, postHooks)
if fs, err = frontend.NewFrontends(cfg.Frontends, r.logic); err == nil {
logic := middleware.NewLogic(cfg.AnnounceInterval, cfg.MinAnnounceInterval, r.storage, preHooks, postHooks)
if fs, err = frontend.NewFrontends(cfg.Frontends, logic); err == nil {
for _, f := range fs {
r.sg.Add(f)
r.frontends = append(r.frontends, f)
}
} else {
err = fmt.Errorf("failed to configure frontends: %w", err)
@@ -68,21 +82,50 @@ func (r *Server) Run(configFilePath string) error {
return err
}
// Dispose shuts down an instance of Server.
func (r *Server) Dispose() {
// Shutdown shuts down an instance of Server.
func (r *Server) Shutdown() {
log.Debug().Msg("stopping frontends and metrics server")
if errs := r.sg.Stop().Wait(); len(errs) > 0 {
log.Error().Errs("errors", errs).Msg("error occurred while shutting down frontends")
}
closeGroup(r.frontends).Msg("frontends stopped")
log.Debug().Msg("stopping logic")
if errs := r.logic.Stop().Wait(); len(errs) > 0 {
log.Error().Errs("errors", errs).Msg("error occurred while shutting down middlewares")
}
log.Debug().Msg("stopping middleware")
closeGroup(r.hooks).Msg("hooks stopped")
log.Debug().Msg("stopping peer store")
if errs := r.storage.Stop().Wait(); len(errs) != 0 {
log.Error().Errs("errors", errs).Msg("error occurred while shutting down peer store")
var err error
if r.storage != nil {
err = r.storage.Close()
} else {
err = errors.New("peer store not configured")
}
log.Err(err).Msg("peer store stopped")
log.Close()
}
func closeGroup(cls []io.Closer) (e *zerolog.Event) {
l := len(cls)
errs := make([]error, l)
wg := sync.WaitGroup{}
wg.Add(l)
for i, cl := range cls {
go func(i int, cl io.Closer) {
defer wg.Done()
if e := cl.Close(); e != nil {
errs[i] = e
}
}(i, cl)
}
wg.Wait()
nnErrs := make([]error, 0, l)
for _, e := range errs {
if e != nil {
nnErrs = append(nnErrs, e)
}
}
var evt *zerolog.Event
if len(nnErrs) > 0 {
evt = log.Error().Errs("errors", nnErrs)
} else {
evt = log.Info()
}
return evt
}