Skip to content

Commit

Permalink
Merge pull request #2975 from oasisprotocol/kostko/fix/tm-init-cancel
Browse files Browse the repository at this point in the history
go/oasis-node: Properly handle shutdown during startup
  • Loading branch information
kostko authored Jun 4, 2020
2 parents fdbbbd1 + a3d2828 commit dff6edc
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 8 deletions.
1 change: 1 addition & 0 deletions .changelog/2975.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
go/oasis-node: Properly handle shutdown during startup
17 changes: 15 additions & 2 deletions go/consensus/tendermint/tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -1119,7 +1119,20 @@ func (t *tendermintService) lazyInit() error {
//
// Defer actually initializing the node till after everything
// else is setup.
t.startFn = func() error {
t.startFn = func() (err error) {
defer func() {
// The node constructor can panic early in case an error occurrs during block replay as
// the fail monitor is not yet initialized in that case. Propagate the error.
if p := recover(); p != nil {
switch pt := p.(type) {
case error:
err = pt
default:
err = fmt.Errorf("%v", pt)
}
}
}()

t.node, err = tmnode.NewNode(tenderConfig,
tendermintPV,
&tmp2p.NodeKey{PrivKey: crypto.SignerToTendermint(t.nodeSigner)},
Expand All @@ -1134,7 +1147,7 @@ func (t *tendermintService) lazyInit() error {
}
if t.stateDb == nil {
// Sanity check for the above wrapDbProvider hack in case the DB provider changes.
panic("tendermint: state database not set")
return fmt.Errorf("tendermint: internal error: state database not set")
}
t.client = tmcli.New(t.node)
t.failMonitor = newFailMonitor(t.Logger, t.node.ConsensusState().Wait)
Expand Down
19 changes: 13 additions & 6 deletions go/oasis-node/cmd/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ func Run(cmd *cobra.Command, args []string) {
cmdCommon.SetIsNodeCmd(true)

node, err := NewNode()
if err != nil {
switch {
case err == nil:
case errors.Is(err, context.Canceled):
// Shutdown requested during startup.
return
default:
os.Exit(1)
}
defer node.Cleanup()
Expand Down Expand Up @@ -482,22 +487,26 @@ func NewTestNode() (*Node, error) {
return newNode(true)
}

func newNode(testNode bool) (*Node, error) { // nolint: gocyclo
func newNode(testNode bool) (node *Node, err error) { // nolint: gocyclo
logger := cmdCommon.Logger()

node := &Node{
node = &Node{
svcMgr: background.NewServiceManager(logger),
}

var startOk bool
defer func() {
if !startOk {
if cErr := node.svcMgr.Ctx.Err(); cErr != nil {
err = cErr
}

node.Stop()
node.Cleanup()
}
}()

if err := cmdCommon.Init(); err != nil {
if err = cmdCommon.Init(); err != nil {
// Common stuff like logger not correcty initialized. Print to stderr
_, _ = fmt.Fprintln(os.Stderr, err)
return nil, err
Expand All @@ -512,8 +521,6 @@ func newNode(testNode bool) (*Node, error) { // nolint: gocyclo
// Load configured values for all registered crash points.
crash.LoadViperArgValues()

var err error

// Open the common node store.
node.commonStore, err = persistent.NewCommonStore(dataDir)
if err != nil {
Expand Down

0 comments on commit dff6edc

Please sign in to comment.