From 3774c5d69a7579abbc95ea5b36fbbc9e027f770f Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Tue, 12 Jan 2021 14:05:08 +0300 Subject: [PATCH] [#304] cmd/neofs-node: Catch closing channel of listener endpoint As in #72 storage application should behave the same way at remote RPC node failures. The simplest way is to restart application. Later we can reinitialize it without downtime. Signed-off-by: Alex Vanin --- cmd/neofs-node/config.go | 17 +++++++++++------ cmd/neofs-node/main.go | 14 ++++++++++++-- cmd/neofs-node/morph.go | 5 ++++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/cmd/neofs-node/config.go b/cmd/neofs-node/config.go index 6b01b3891..bfe5a9594 100644 --- a/cmd/neofs-node/config.go +++ b/cmd/neofs-node/config.go @@ -142,6 +142,10 @@ const ( type cfg struct { ctx context.Context + ctxCancel func() + + internalErr chan error // channel for internal application errors at runtime + viper *viper.Viper log *zap.Logger @@ -290,12 +294,13 @@ func initCfg(path string) *cfg { state := newNetworkState() c := &cfg{ - ctx: context.Background(), - viper: viperCfg, - log: log, - wg: new(sync.WaitGroup), - key: key, - apiVersion: pkg.SDKVersion(), + ctx: context.Background(), + internalErr: make(chan error), + viper: viperCfg, + log: log, + wg: new(sync.WaitGroup), + key: key, + apiVersion: pkg.SDKVersion(), cfgAccounting: cfgAccounting{ scriptHash: u160Accounting, fee: fixedn.Fixed8(viperCfg.GetInt(cfgAccountingFee)), diff --git a/cmd/neofs-node/main.go b/cmd/neofs-node/main.go index 218e5c7f6..440fcdee1 100644 --- a/cmd/neofs-node/main.go +++ b/cmd/neofs-node/main.go @@ -1,10 +1,12 @@ package main import ( + "context" "flag" "log" "github.com/nspcc-dev/neofs-node/pkg/util/grace" + "go.uber.org/zap" ) func fatalOnErr(err error) { @@ -29,7 +31,7 @@ func main() { } func initApp(c *cfg) { - c.ctx = grace.NewGracefulContext(nil) + c.ctx, c.ctxCancel = context.WithCancel(grace.NewGracefulContext(nil)) initGRPC(c) @@ -56,7 +58,15 @@ func bootUp(c *cfg) { func wait(c *cfg) { c.log.Info("application started") - <-c.ctx.Done() + select { + case <-c.ctx.Done(): // graceful shutdown + case err := <-c.internalErr: // internal application error + close(c.internalErr) + c.ctxCancel() + + c.log.Warn("internal application error", + zap.String("message", err.Error())) + } } func shutdown(c *cfg) { diff --git a/cmd/neofs-node/morph.go b/cmd/neofs-node/morph.go index 09f4752c1..a34661975 100644 --- a/cmd/neofs-node/morph.go +++ b/cmd/neofs-node/morph.go @@ -1,6 +1,7 @@ package main import ( + "context" "fmt" "github.com/nspcc-dev/neo-go/pkg/util" @@ -51,7 +52,9 @@ func listenMorphNotifications(c *cfg) { }) fatalOnErr(err) - c.workers = append(c.workers, newWorkerFromFunc(lis.Listen)) + c.workers = append(c.workers, newWorkerFromFunc(func(ctx context.Context) { + lis.ListenWithError(ctx, c.internalErr) + })) setNetmapNotificationParser(c, newEpochNotification, netmapEvent.ParseNewEpoch) registerNotificationHandlers(c.cfgNetmap.scriptHash, lis, c.cfgNetmap.parsers, c.cfgNetmap.subscribers)