Skip to content

Commit

Permalink
fix factory pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
kocubinski committed Oct 25, 2024
1 parent ca06258 commit 20e7ec1
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 68 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"request": "launch",
"mode": "debug",
"program": "${workspaceFolder}/simapp/v2/simdv2",
"args": ["start"],
"args": ["config", "home"],
"buildFlags": ""
},
{
Expand Down
1 change: 1 addition & 0 deletions scripts/init-simapp-v2.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
set -x

SIMD_BIN=${SIMD_BIN:=$(which simdv2 2>/dev/null)}

Expand Down
10 changes: 7 additions & 3 deletions server/v2/api/grpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,13 @@ func New[T transaction.Tx](
return srv, nil
}

func (s *Server[T]) WithConfigOptions(opts ...CfgOption) *Server[T] {
s.cfgOptions = append(s.cfgOptions, opts...)
return s
// NewWithConfigOptions creates a new GRPC server with the provided config options.
// It is *not* a fully functional server (since it has been created without dependencies)
// The returned server should only be used to get and set configuration.
func NewWithConfigOptions[T transaction.Tx](opts ...CfgOption) *Server[T] {
return &Server[T]{
cfgOptions: opts,
}
}

func (s *Server[T]) StartCmdFlags() *pflag.FlagSet {
Expand Down
14 changes: 9 additions & 5 deletions server/v2/api/rest/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ func New[T transaction.Tx](
return srv, nil
}

// NewWithConfigOptions creates a new REST server with the provided config options.
// It is *not* a fully functional server (since it has been created without dependencies)
// The returned server should only be used to get and set configuration.
func NewWithConfigOptions[T transaction.Tx](opts ...CfgOption) *Server[T] {
return &Server[T]{
cfgOptions: opts,
}
}

func (s *Server[T]) Name() string {
return ServerName
}
Expand Down Expand Up @@ -85,11 +94,6 @@ func (s *Server[T]) Stop(ctx context.Context) error {
return s.httpServer.Shutdown(ctx)
}

func (s *Server[T]) WithConfigOptions(opts ...CfgOption) *Server[T] {
s.cfgOptions = append(s.cfgOptions, opts...)
return s
}

func (s *Server[T]) Config() any {
if s.config == nil || s.config.Address == "" {
cfg := DefaultConfig()
Expand Down
3 changes: 1 addition & 2 deletions server/v2/api/rest/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ func TestServerConfig(t *testing.T) {
{
name: "Custom configuration",
setupFunc: func() *Config {
s := &Server[transaction.Tx]{}
s = s.WithConfigOptions(func(config *Config) {
s := NewWithConfigOptions[transaction.Tx](func(config *Config) {
config.Enable = false
})
return s.Config().(*Config)
Expand Down
10 changes: 7 additions & 3 deletions server/v2/cometbft/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,13 @@ func New[T transaction.Tx](
return srv, nil
}

func (s *CometBFTServer[T]) WithConfigOptions(opts ...CfgOption) *CometBFTServer[T] {
s.cfgOptions = append(s.cfgOptions, opts...)
return s
// NewWithConfigOptions creates a new CometBFT server with the provided config options.
// It is *not* a fully functional server (since it has been created without dependencies)
// The returned server should only be used to get and set configuration.
func NewWithConfigOptions[T transaction.Tx](opts ...CfgOption) *CometBFTServer[T] {
return &CometBFTServer[T]{
cfgOptions: opts,
}
}

func (s *CometBFTServer[T]) Name() string {
Expand Down
55 changes: 35 additions & 20 deletions server/v2/command_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package serverv2

import (
"errors"
"io"
"os"
"path/filepath"
"strings"
Expand All @@ -20,7 +21,9 @@ type CommandFactory struct {
defaultHomeDir string
envPrefix string
configWriter ConfigWriter
logger log.Logger
loggerFactory func(server.ConfigMap, io.Writer) (log.Logger, error)

logger log.Logger
// TODO remove this field
// this viper handle is kept because certain commands in server/v2 fetch a viper instance
// from the command context in order to read the config.
Expand Down Expand Up @@ -96,11 +99,10 @@ func WithConfigWriter(configWriter ConfigWriter) CommandFactoryOption {
}
}

// SetLogger sets the logger for the command factory.
// If set the logger will be set in the command context in EnhanceCommand.
func WithLogger(logger log.Logger) CommandFactoryOption {
// WithLoggerFactory sets the logger factory for the command factory.
func WithLoggerFactory(loggerFactory func(server.ConfigMap, io.Writer) (log.Logger, error)) CommandFactoryOption {
return func(f *CommandFactory) error {
f.logger = logger
f.loggerFactory = loggerFactory
return nil
}
}
Expand All @@ -113,7 +115,6 @@ func WithLogger(logger log.Logger) CommandFactoryOption {
// --home: directory for config and data
//
// It also sets the environment variable prefix for the viper instance.
// It sets the logger and viper in the command context (if present)
func (f *CommandFactory) EnhanceCommand(cmd *cobra.Command) {
pflags := cmd.PersistentFlags()
pflags.String(FlagLogLevel, "info", "The logging level (trace|debug|info|warn|error|fatal|panic|disabled or '*:<level>,<key>:<level>')")
Expand All @@ -123,47 +124,61 @@ func (f *CommandFactory) EnhanceCommand(cmd *cobra.Command) {
viper.SetEnvPrefix(f.envPrefix)
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
viper.AutomaticEnv()
if f.vipr != nil && f.logger != nil {
SetCmdServerContext(cmd, f.vipr, f.logger)
}
}

// ParseCommand parses args against the input rootCmd CLI skeleton then returns the target subcommand and
// a fully realized config map.
// EnhanceCommandContext sets the viper and logger in the command context.
func (f *CommandFactory) EnhanceCommandContext(cmd *cobra.Command) {
SetCmdServerContext(cmd, f.vipr, f.logger)
}

// ParseCommand parses args against the input rootCmd CLI skeleton then returns the target subcommand,
// a fully realized config map, and a properly configured logger.
// If `WithConfigWriter` was set in the factory options, the config writer will be used to write the app.toml file.
func (f *CommandFactory) ParseCommand(rootCmd *cobra.Command, args []string) (*cobra.Command, server.ConfigMap, error) {
// Internally a viper instance is created and used to bind the flags to the config map.
// Future invocations of EnhanceCommandContext will set the viper instance and logger in the command context.
func (f *CommandFactory) ParseCommand(
rootCmd *cobra.Command,
args []string,
) (*cobra.Command, server.ConfigMap, log.Logger, error) {
f.EnhanceCommand(rootCmd)
cmd, _, err := rootCmd.Traverse(args)
if err != nil {
return nil, nil, err
return nil, nil, nil, err
}
if err = cmd.ParseFlags(args); err != nil {
// help requested, return the command early
if errors.Is(err, pflag.ErrHelp) {
return cmd, nil, nil
return cmd, nil, nil, nil
}
return nil, nil, err
return nil, nil, nil, err
}
home, err := cmd.Flags().GetString(FlagHome)
if err != nil {
return nil, nil, err
return nil, nil, nil, err
}
configDir := filepath.Join(home, "config")
if f.configWriter != nil {
// create app.toml if it does not already exist
if _, err = os.Stat(filepath.Join(configDir, "app.toml")); os.IsNotExist(err) {
if err = f.configWriter.WriteConfig(configDir); err != nil {
return nil, nil, err
return nil, nil, nil, err
}
}
}
f.vipr, err = ReadConfig(configDir)
if err != nil {
return nil, nil, err
return nil, nil, nil, err
}
if err = f.vipr.BindPFlags(cmd.Flags()); err != nil {
return nil, nil, err
return nil, nil, nil, err
}

if f.loggerFactory != nil {
f.logger, err = f.loggerFactory(f.vipr.AllSettings(), cmd.OutOrStdout())
if err != nil {
return nil, nil, nil, err
}
}

return cmd, f.vipr.AllSettings(), nil
return cmd, f.vipr.AllSettings(), f.logger, nil
}
3 changes: 1 addition & 2 deletions simapp/v2/simdv2/cmd/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ func initRootCmd[T transaction.Tx](
// build CLI skeleton for initial config parsing or a client application invocation
if deps.simApp == nil {
if deps.consensusComponent == nil {
comet := &cometbft.CometBFTServer[T]{}
deps.consensusComponent = comet.WithConfigOptions(initCometConfig())
deps.consensusComponent = cometbft.NewWithConfigOptions[T](initCometConfig())
}
return serverv2.AddCommands[T](
rootCmd,
Expand Down
39 changes: 18 additions & 21 deletions simapp/v2/simdv2/cmd/root_di.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,25 @@ import (
func NewRootCmd[T transaction.Tx](
args ...string,
) (*cobra.Command, error) {
cmd := &cobra.Command{Use: "simdv2", SilenceErrors: true}
configWriter, err := initRootCmd(cmd, log.NewNopLogger(), commandDependencies[T]{})
rootCommand := &cobra.Command{
Use: "simdv2",
SilenceErrors: true,
}
configWriter, err := initRootCmd(rootCommand, log.NewNopLogger(), commandDependencies[T]{})
if err != nil {
return nil, err
}
stdHomeDirOption := serverv2.WithStdDefaultHomeDir(".simappv2")
factory, err := serverv2.NewCommandFactory(serverv2.WithConfigWriter(configWriter), stdHomeDirOption)
factory, err := serverv2.NewCommandFactory(
serverv2.WithConfigWriter(configWriter),
serverv2.WithStdDefaultHomeDir(".simappv2"),
serverv2.WithLoggerFactory(serverv2.NewLogger),
)
if err != nil {
return nil, err
}

// returns the target subcommand and a fully realized config map
subCommand, configMap, err := factory.ParseCommand(cmd, args)
if err != nil {
return nil, err
}
// create default logger
logger, err := serverv2.NewLogger(configMap, cmd.OutOrStdout())
subCommand, configMap, logger, err := factory.ParseCommand(rootCommand, args)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -75,23 +76,19 @@ func NewRootCmd[T transaction.Tx](
}
}

rootCommand := &cobra.Command{
Use: "simdv2",
Short: "simulation app",
PersistentPreRunE: rootCommandPersistentPreRun(clientCtx),
}
factory, err = serverv2.NewCommandFactory(stdHomeDirOption, serverv2.WithLogger(logger))
if err != nil {
return nil, err
}
factory.EnhanceCommand(rootCommand)

commandDeps := commandDependencies[T]{
globalAppConfig: configMap,
txConfig: clientCtx.TxConfig,
moduleManager: moduleManager,
simApp: simApp,
}
rootCommand = &cobra.Command{
Use: "simdv2",
Short: "simulation app",
SilenceErrors: true,
PersistentPreRunE: rootCommandPersistentPreRun(clientCtx),
}
factory.EnhanceCommandContext(rootCommand)
_, err = initRootCmd(rootCommand, logger, commandDeps)
if err != nil {
return nil, err
Expand Down
4 changes: 2 additions & 2 deletions simapp/v2/simdv2/cmd/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,9 +335,9 @@ func initTestnetFiles[T transaction.Tx](
serverCfg := serverv2.DefaultServerConfig()
serverCfg.MinGasPrices = args.minGasPrices

cometServer := (&cometbft.CometBFTServer[T]{}).WithConfigOptions(cometbft.OverwriteDefaultConfigTomlConfig(nodeConfig))
cometServer := cometbft.NewWithConfigOptions[T](cometbft.OverwriteDefaultConfigTomlConfig(nodeConfig))
storeServer := &store.Server[T]{}
grpcServer := (&grpc.Server[T]{}).WithConfigOptions(grpc.OverwriteDefaultConfig(grpcConfig))
grpcServer := grpc.NewWithConfigOptions[T](grpc.OverwriteDefaultConfig(grpcConfig))
server := serverv2.NewServer[T](serverCfg, cometServer, storeServer, grpcServer)
err = server.WriteConfig(filepath.Join(nodeDir, "config"))
if err != nil {
Expand Down
9 changes: 0 additions & 9 deletions x/genutil/v2/types.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
package v2

import (
"context"
"encoding/json"

sdk "github.com/cosmos/cosmos-sdk/types"
)

// AppExporter is a function that dumps all app state to
// JSON-serializable structure and returns the current validator set.
type AppExporter func(
ctx context.Context,
height int64,
jailAllowedAddrs []string,
) (ExportedApp, error)

// ExportedApp represents an exported app state, along with
// validators, consensus params and latest app height.
type ExportedApp struct {
Expand Down

0 comments on commit 20e7ec1

Please sign in to comment.