diff --git a/internal/app/kwild/cmd/server/root.go b/internal/app/kwild/cmd/server/root.go index 4b4c4f86c..33840a139 100644 --- a/internal/app/kwild/cmd/server/root.go +++ b/internal/app/kwild/cmd/server/root.go @@ -1,6 +1,11 @@ package server import ( + "context" + "os" + "os/signal" + "syscall" + "github.com/kwilteam/kwil-db/internal/app/kwild/config" // shorthand for chain client service @@ -20,12 +25,23 @@ var startCmd = &cobra.Command{ Long: "Starts node with Kwild and CometBFT services", RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() + + signalChan := make(chan os.Signal, 1) + signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) + ctx, cancel := context.WithCancel(ctx) + + go func() { + <-signalChan + cancel() + }() + svr, err := server.BuildKwildServer(ctx) if err != nil { return err } return svr.Start(ctx) + }, } diff --git a/internal/app/kwild/server/root.go b/internal/app/kwild/server/root.go index 2d9671b10..f51273fe9 100644 --- a/internal/app/kwild/server/root.go +++ b/internal/app/kwild/server/root.go @@ -6,7 +6,6 @@ import ( "fmt" "net" "path/filepath" - "sync" "time" // kwil-db @@ -132,29 +131,37 @@ func (c *closeFuncs) addCloser(f func() error) { // closeAll concurrently closes all closers func (c *closeFuncs) closeAll() error { - errs := make([]error, 0) - errCh := make(chan error, len(c.closers)) - wg := sync.WaitGroup{} - + var errs []error for _, f := range c.closers { - wg.Add(1) - go func(f func() error) { - err := f() - if err != nil { - errCh <- err - } - wg.Done() - }(f) - } - - wg.Wait() - close(errCh) - - for err := range errCh { - errs = append(errs, err) + if err := f(); err != nil { + errs = append(errs, err) + } } return errors.Join(errs...) + // errs := make([]error, 0) + // errCh := make(chan error, len(c.closers)) + // wg := sync.WaitGroup{} + + // for _, f := range c.closers { + // wg.Add(1) + // go func(f func() error) { + // err := f() + // if err != nil { + // errCh <- err + // } + // wg.Done() + // }(f) + // } + + // wg.Wait() + // close(errCh) + + // for err := range errCh { + // errs = append(errs, err) + // } + + // return errors.Join(errs...) } func buildAbci(d *coreDependencies, closer *closeFuncs, datasetsModule abci.DatasetsModule, validatorModule abci.ValidatorModule, diff --git a/internal/app/kwild/server/server.go b/internal/app/kwild/server/server.go index 15c4f17e2..08252e68d 100644 --- a/internal/app/kwild/server/server.go +++ b/internal/app/kwild/server/server.go @@ -42,6 +42,12 @@ func (s *Server) Start(ctx context.Context) error { } } }() + defer func() { + err := s.closers.closeAll() + if err != nil { + s.log.Error("failed to close resource:", zap.Error(err)) + } + }() s.log.Info("starting server...") @@ -91,13 +97,6 @@ func (s *Server) Start(ctx context.Context) error { err := group.Wait() - defer func() { - err := s.closers.closeAll() - if err != nil { - s.log.Error("failed to close resource:", zap.Error(err)) - } - }() - if err != nil { if errors.Is(err, context.Canceled) { s.log.Info("server context is canceled") diff --git a/pkg/kv/badger/db.go b/pkg/kv/badger/db.go index fd517d634..fbe089cbc 100644 --- a/pkg/kv/badger/db.go +++ b/pkg/kv/badger/db.go @@ -16,8 +16,9 @@ import ( // It takes a path, like path/to/db, where the database will be stored. func NewBadgerDB(ctx context.Context, path string, options *Options) (*BadgerDB, error) { b := &BadgerDB{ - logger: log.NewNoOp(), - gcInterval: 5 * time.Minute, + logger: log.NewNoOp(), + gcInterval: 5 * time.Minute, + gcDiscardRatio: 0.5, } badgerOpts := badger.DefaultOptions(path) @@ -51,6 +52,9 @@ type BadgerDB struct { // gcInterval is the interval at which the database is garbage collected. gcInterval time.Duration + // gcDiscardRatio is the ratio of discarded keys to total keys. + gcDiscardRatio float64 + // logger is the logger for the database. logger log.Logger } @@ -182,11 +186,18 @@ type Options struct { // Logger is the logger to use for the database. Logger log.Logger + + // GarbageCollectionDiscardRatio is the ratio at which the garbage collector discards + // old versions of a value. It must be between 0 and 1. + // Lower values will have a higher performance hit, but will use less disk space. + GarbageCollectionDiscardRatio float64 } // applyToBadgerOpts applies the options to the badger options. func (o *Options) applyToBadgerOpts(opts *badger.Options) { opts.SyncWrites = o.GuaranteeFSync + opts.CompactL0OnClose = true + opts.NumCompactors = 2 } func (o *Options) applyToDB(db *BadgerDB) { @@ -197,6 +208,11 @@ func (o *Options) applyToDB(db *BadgerDB) { if o.GarbageCollectionInterval != 0 { db.gcInterval = o.GarbageCollectionInterval } + + if o.GarbageCollectionDiscardRatio != 0 { + db.gcDiscardRatio = o.GarbageCollectionDiscardRatio + } + } // badgerLogger implements the badger.Logger interface.