diff --git a/cmd/lilypad/solver.go b/cmd/lilypad/solver.go index c990121b..332fb082 100644 --- a/cmd/lilypad/solver.go +++ b/cmd/lilypad/solver.go @@ -1,8 +1,12 @@ package lilypad import ( + "fmt" + optionsfactory "github.com/lilypad-tech/lilypad/pkg/options" "github.com/lilypad-tech/lilypad/pkg/solver" + "github.com/lilypad-tech/lilypad/pkg/solver/store" + db "github.com/lilypad-tech/lilypad/pkg/solver/store/db" memorystore "github.com/lilypad-tech/lilypad/pkg/solver/store/memory" "github.com/lilypad-tech/lilypad/pkg/system" "github.com/lilypad-tech/lilypad/pkg/web3" @@ -19,7 +23,6 @@ func newSolverCmd() *cobra.Command { Long: "Start the lilypad solver service.", Example: "", RunE: func(cmd *cobra.Command, _ []string) error { - network, _ := cmd.Flags().GetString("network") options, err := optionsfactory.ProcessSolverOptions(options, network) if err != nil { @@ -57,7 +60,7 @@ func runSolver(cmd *cobra.Command, options solver.SolverOptions, network string) return err } - solverStore, err := memorystore.NewSolverStoreMemory() + solverStore, err := getSolverStore(options.Store) if err != nil { return err } @@ -79,3 +82,25 @@ func runSolver(cmd *cobra.Command, options solver.SolverOptions, network string) } } } + +func getSolverStore(options store.StoreOptions) (store.SolverStore, error) { + var solverStore store.SolverStore + var err error + + switch options.Type { + case "database": + solverStore, err = db.NewSolverStoreDatabase(options.ConnStr, options.GormLogLevel) + if err != nil { + return nil, err + } + case "memory": + solverStore, err = memorystore.NewSolverStoreMemory() + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("expected solver store type database or memory, but received: %s", options.Type) + } + + return solverStore, nil +} diff --git a/pkg/options/solver.go b/pkg/options/solver.go index 4bc2b328..ae16452b 100644 --- a/pkg/options/solver.go +++ b/pkg/options/solver.go @@ -9,6 +9,7 @@ import ( func NewSolverOptions() solver.SolverOptions { options := solver.SolverOptions{ Server: GetDefaultServerOptions(), + Store: GetDefaultStoreOptions(), Web3: GetDefaultWeb3Options(), Services: GetDefaultServicesOptions(), Telemetry: GetDefaultTelemetryOptions(), @@ -19,19 +20,24 @@ func NewSolverOptions() solver.SolverOptions { } func AddSolverCliFlags(cmd *cobra.Command, options *solver.SolverOptions) { - AddWeb3CliFlags(cmd, &options.Web3) AddServerCliFlags(cmd, &options.Server) + AddStoreCliFlags(cmd, &options.Store) + AddWeb3CliFlags(cmd, &options.Web3) AddServicesCliFlags(cmd, &options.Services) AddTelemetryCliFlags(cmd, &options.Telemetry) AddMetricsCliFlags(cmd, &options.Metrics) } func CheckSolverOptions(options solver.SolverOptions) error { - err := CheckWeb3Options(options.Web3) + err := CheckServerOptions(options.Server) + if err != nil { + return err + } + err = CheckStoreOptions(options.Store) if err != nil { return err } - err = CheckServerOptions(options.Server) + err = CheckWeb3Options(options.Web3) if err != nil { return err } diff --git a/pkg/options/store.go b/pkg/options/store.go new file mode 100644 index 00000000..600c0b74 --- /dev/null +++ b/pkg/options/store.go @@ -0,0 +1,48 @@ +package options + +import ( + "fmt" + + "github.com/lilypad-tech/lilypad/pkg/solver/store" + "github.com/spf13/cobra" +) + +func GetDefaultStoreOptions() store.StoreOptions { + return store.StoreOptions{ + Type: GetDefaultServeOptionString("STORE_TYPE", "database"), + ConnStr: GetDefaultServeOptionString("STORE_CONN_STR", ""), + GormLogLevel: GetDefaultServeOptionString("STORE_GORM_LOG_LEVEL", "silent"), + } +} + +func AddStoreCliFlags(cmd *cobra.Command, storeOptions *store.StoreOptions) { + cmd.PersistentFlags().StringVar( + &storeOptions.Type, "store-type", storeOptions.Type, + `The store type used by the solver, one of "database" or "memory" (STORE_TYPE).`, + ) + cmd.PersistentFlags().StringVar( + &storeOptions.ConnStr, "store-conn-str", storeOptions.ConnStr, + `The database store connection string (STORE_CONN_STR).`, + ) + cmd.PersistentFlags().StringVar( + &storeOptions.GormLogLevel, "store-gorm-log-level", storeOptions.GormLogLevel, + `The database store gorm log level, one of "silent", "info", "error", "warn" (STORE_GORM_LOG_LEVEL).`, + ) +} + +func CheckStoreOptions(options store.StoreOptions) error { + if options.Type != "database" && options.Type != "memory" { + return fmt.Errorf("STORE_TYPE must be \"database\" or \"memory\"") + } + if options.Type == "database" && options.ConnStr == "" { + return fmt.Errorf("STORE_CONN_STR is required when using the database store") + } + if options.GormLogLevel != "silent" && + options.GormLogLevel != "info" && + options.GormLogLevel != "error" && + options.GormLogLevel != "warn" { + return fmt.Errorf("STORE_GORM_LOG_LEVEL must be \"silent\", \"info\", \"error\", or \"warn\"") + } + + return nil +} diff --git a/pkg/solver/solver.go b/pkg/solver/solver.go index 314b2ac3..e519795b 100644 --- a/pkg/solver/solver.go +++ b/pkg/solver/solver.go @@ -15,8 +15,9 @@ import ( ) type SolverOptions struct { - Web3 web3.Web3Options Server http.ServerOptions + Store store.StoreOptions + Web3 web3.Web3Options Services data.ServiceConfig Telemetry system.TelemetryOptions Metrics system.MetricsOptions diff --git a/pkg/solver/store/db/db.go b/pkg/solver/store/db/db.go index 5030338b..0b4ed89f 100644 --- a/pkg/solver/store/db/db.go +++ b/pkg/solver/store/db/db.go @@ -16,10 +16,19 @@ type SolverStoreDatabase struct { db *gorm.DB } -func NewSolverStoreDatabase(connStr string, silenceLogs bool) (*SolverStoreDatabase, error) { +func NewSolverStoreDatabase(connStr string, gormLogLevel string) (*SolverStoreDatabase, error) { config := &gorm.Config{} - if silenceLogs { + switch gormLogLevel { + case "silent": config.Logger = logger.Default.LogMode(logger.Silent) + case "info": + config.Logger = logger.Default.LogMode(logger.Info) + case "error": + config.Logger = logger.Default.LogMode(logger.Error) + case "warn": + config.Logger = logger.Default.LogMode(logger.Warn) + default: + return nil, fmt.Errorf("expected solver store gorm log level silent, info, error, or warn, but received: %s", gormLogLevel) } db, err := gorm.Open(postgres.Open(connStr), config) diff --git a/pkg/solver/store/store.go b/pkg/solver/store/store.go index 00a9132b..61f86045 100644 --- a/pkg/solver/store/store.go +++ b/pkg/solver/store/store.go @@ -6,6 +6,12 @@ import ( "github.com/lilypad-tech/lilypad/pkg/data" ) +type StoreOptions struct { + Type string + ConnStr string + GormLogLevel string +} + type GetJobOffersQuery struct { JobCreator string `json:"job_creator"` // this means job offers that have not been matched at all yet diff --git a/pkg/solver/store/store_test.go b/pkg/solver/store/store_test.go index 57090a68..84a5e02a 100644 --- a/pkg/solver/store/store_test.go +++ b/pkg/solver/store/store_test.go @@ -1349,7 +1349,7 @@ func setupStores(t *testing.T) []storeConfig { } initDatabase := func() func() store.SolverStore { - db, err := databasestore.NewSolverStoreDatabase(DB_CONN_STR, true) + db, err := databasestore.NewSolverStoreDatabase(DB_CONN_STR, "silent") if err != nil { t.Fatalf("Failed to create database store: %v", err) } diff --git a/stack b/stack index 3521d307..f2974f82 100755 --- a/stack +++ b/stack @@ -195,6 +195,9 @@ function solver() { load-local-env export WEB3_PRIVATE_KEY=${SOLVER_PRIVATE_KEY} export LOG_LEVEL=debug + export STORE_TYPE=database + export STORE_CONN_STR=postgres://postgres:postgres@localhost:5432/solver-db?sslmode=disable + export STORE_GORM_LOG_LEVEL=silent go run . solver --network dev "$@" }