forked from TrueCloudLab/frostfs-node
156 lines
3.2 KiB
Go
156 lines
3.2 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"sync"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/misc"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
|
httputil "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/http"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
"github.com/spf13/viper"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
const (
|
|
// ErrorReturnCode returns when application crashed at initialization stage.
|
|
ErrorReturnCode = 1
|
|
|
|
// SuccessReturnCode returns when application closed without panic.
|
|
SuccessReturnCode = 0
|
|
|
|
EnvPrefix = "FROSTFS_IR"
|
|
)
|
|
|
|
var (
|
|
wg = new(sync.WaitGroup)
|
|
intErr = make(chan error) // internal inner ring errors
|
|
logPrm = new(logger.Prm)
|
|
innerRing *innerring.Server
|
|
httpServers []*httputil.Server
|
|
log *logger.Logger
|
|
cfg *viper.Viper
|
|
configFile *string
|
|
configDir *string
|
|
)
|
|
|
|
func exitErr(err error) {
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(ErrorReturnCode)
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
configFile = flag.String("config", "", "path to config")
|
|
configDir = flag.String("config-dir", "", "path to config directory")
|
|
versionFlag := flag.Bool("version", false, "frostfs-ir node version")
|
|
flag.Parse()
|
|
|
|
if *versionFlag {
|
|
fmt.Print(misc.BuildInfo("FrostFS Inner Ring node"))
|
|
|
|
os.Exit(SuccessReturnCode)
|
|
}
|
|
|
|
var err error
|
|
cfg, err = newConfig()
|
|
exitErr(err)
|
|
|
|
err = logPrm.SetLevelString(
|
|
cfg.GetString("logger.level"),
|
|
)
|
|
exitErr(err)
|
|
|
|
log, err = logger.NewLogger(logPrm)
|
|
exitErr(err)
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
initHTTPServers(cfg)
|
|
|
|
innerRing, err = innerring.New(ctx, log, cfg, intErr)
|
|
exitErr(err)
|
|
|
|
// start HTTP servers
|
|
for _, srv := range httpServers {
|
|
wg.Add(1)
|
|
go func(srv *httputil.Server) {
|
|
exitErr(srv.Serve())
|
|
wg.Done()
|
|
}(srv)
|
|
}
|
|
|
|
// start inner ring
|
|
err = innerRing.Start(ctx, intErr)
|
|
exitErr(err)
|
|
|
|
log.Info(logs.CommonApplicationStarted,
|
|
zap.String("version", misc.Version))
|
|
|
|
watchForSignal(cancel)
|
|
|
|
<-ctx.Done() // graceful shutdown
|
|
log.Debug(logs.FrostFSNodeWaitingForAllProcessesToStop)
|
|
wg.Wait()
|
|
|
|
log.Info(logs.FrostFSIRApplicationStopped)
|
|
}
|
|
|
|
func initHTTPServers(cfg *viper.Viper) {
|
|
items := []struct {
|
|
cfgPrefix string
|
|
handler func() http.Handler
|
|
}{
|
|
{"pprof", httputil.Handler},
|
|
{"prometheus", promhttp.Handler},
|
|
}
|
|
|
|
httpServers = make([]*httputil.Server, 0, len(items))
|
|
|
|
for _, item := range items {
|
|
if !cfg.GetBool(item.cfgPrefix + ".enabled") {
|
|
log.Info(item.cfgPrefix + " is disabled, skip")
|
|
continue
|
|
}
|
|
|
|
addr := cfg.GetString(item.cfgPrefix + ".address")
|
|
|
|
var prm httputil.HTTPSrvPrm
|
|
|
|
prm.Address = addr
|
|
prm.Handler = item.handler()
|
|
|
|
httpServers = append(httpServers,
|
|
httputil.New(prm,
|
|
httputil.WithShutdownTimeout(
|
|
cfg.GetDuration(item.cfgPrefix+".shutdown_timeout"),
|
|
),
|
|
),
|
|
)
|
|
}
|
|
}
|
|
|
|
func shutdown() {
|
|
innerRing.Stop()
|
|
|
|
// shut down HTTP servers
|
|
for _, srv := range httpServers {
|
|
wg.Add(1)
|
|
go func(srv *httputil.Server) {
|
|
err := srv.Shutdown()
|
|
if err != nil {
|
|
log.Debug(logs.FrostFSIRCouldNotShutdownHTTPServer,
|
|
zap.String("error", err.Error()),
|
|
)
|
|
}
|
|
wg.Done()
|
|
}(srv)
|
|
}
|
|
}
|