diff --git a/cmd/go-quai/start.go b/cmd/go-quai/start.go index 91278077e4..299c9ac2eb 100644 --- a/cmd/go-quai/start.go +++ b/cmd/go-quai/start.go @@ -4,6 +4,7 @@ import ( "context" "os" "os/signal" + "sync" "syscall" "github.com/spf13/cobra" @@ -70,7 +71,8 @@ func runStart(cmd *cobra.Command, args []string) error { logLevel := cmd.Flag(utils.LogLevelFlag.Name).Value.String() // create instance of consensus backend - consensus, err := utils.StartQuaiBackend(logLevel) + var nodeWG sync.WaitGroup + consensus, err := utils.StartQuaiBackend(ctx, logLevel, &nodeWG) if err != nil { log.Fatalf("error creating consensus backend: %s", err) } @@ -98,6 +100,7 @@ func runStart(cmd *cobra.Command, args []string) error { <-ch log.Warnf("Received 'stop' signal, shutting down gracefully...") cancel() + nodeWG.Wait() if err := node.Stop(); err != nil { panic(err) } diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index 6bd67b19c2..5d2e463660 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -1,10 +1,12 @@ package utils import ( + "context" "fmt" "io" "os" "runtime" + "sync" "time" "github.com/dominant-strategies/go-quai/common" @@ -30,42 +32,41 @@ type quaiConfig struct { } // Create a new instance of the QuaiBackend consensus service -func StartQuaiBackend(logLevel string) (*quai.QuaiBackend, error) { - var logger *log.LogWrapper - // Make full node - go func() { - // Create the prime logger with the log file path - logger = log.New("nodelogs/prime.log", logLevel) - logger.Info("Starting Prime") - stackPrime := makeFullNode(nil, logger) - defer stackPrime.Close() - StartNode(stackPrime) - stackPrime.Wait() - }() +func StartQuaiBackend(ctx context.Context, logLevel string, nodeWG *sync.WaitGroup) (*quai.QuaiBackend, error) { + startNode := func(logPath string, location common.Location) { + nodeWG.Add(1) + go func() { + defer nodeWG.Done() + logger := log.New(logPath, logLevel) + logger.Info("Starting Node at location", "location", location) + stack := makeFullNode(location, logger) + StartNode(stack) + // Create a channel to signal when stack.Wait() is done + done := make(chan struct{}) + go func() { + stack.Wait() + close(done) + }() + + select { + case <-done: + logger.Info("Node stopped normally") + stack.Close() + return + case <-ctx.Done(): + logger.Info("Context cancelled, shutting down node") + stack.Close() + return + } + }() + } + // Start nodes in separate goroutines + startNode("nodelogs/prime.log", nil) time.Sleep(2 * time.Second) - - go func() { - // Create the prime logger with the log file path - logger = log.New("nodelogs/region-0.log", logLevel) - logger.Info("Starting Region") - stackRegion := makeFullNode(common.Location{0}, logger) - defer stackRegion.Close() - StartNode(stackRegion) - stackRegion.Wait() - }() - + startNode("nodelogs/region-0.log", common.Location{0}) time.Sleep(2 * time.Second) - - go func() { - // Create the prime logger with the log file path - logger = log.New("nodelogs/zone-0-0.log", logLevel) - log.Info("Starting Zone") - stackZone := makeFullNode(common.Location{0, 0}, logger) - defer stackZone.Close() - StartNode(stackZone) - stackZone.Wait() - }() + startNode("nodelogs/zone-0-0.log", common.Location{0, 0}) return &quai.QuaiBackend{}, nil } diff --git a/ethdb/leveldb/leveldb.go b/ethdb/leveldb/leveldb.go index 6f6de32985..1da3053de3 100644 --- a/ethdb/leveldb/leveldb.go +++ b/ethdb/leveldb/leveldb.go @@ -136,11 +136,11 @@ func (db *Database) Close() error { defer db.quitLock.Unlock() if db.quitChan != nil { - errc := make(chan error) - db.quitChan <- errc - if err := <-errc; err != nil { - db.logger.Error("Metrics collection failed", "err", err) - } + // errc := make(chan error) + // db.quitChan <- errc + // if err := <-errc; err != nil { + // db.logger.Error("Metrics collection failed", "err", err) + // } db.quitChan = nil } return db.db.Close()