aboutsummaryrefslogtreecommitdiff
path: root/backend/cmd
diff options
context:
space:
mode:
authorGravatar Anshul Gupta <ansg191@anshulg.com> 2024-08-05 18:55:10 -0700
committerGravatar Anshul Gupta <ansg191@anshulg.com> 2024-08-05 18:55:19 -0700
commitb96fcd1a54a46a95f98467b49a051564bc21c23c (patch)
tree93caeeb05f8d6310e241095608ea2428c749b18c /backend/cmd
downloadibd-trader-b96fcd1a54a46a95f98467b49a051564bc21c23c.tar.gz
ibd-trader-b96fcd1a54a46a95f98467b49a051564bc21c23c.tar.zst
ibd-trader-b96fcd1a54a46a95f98467b49a051564bc21c23c.zip
Initial Commit
Diffstat (limited to 'backend/cmd')
-rw-r--r--backend/cmd/main.go159
1 files changed, 159 insertions, 0 deletions
diff --git a/backend/cmd/main.go b/backend/cmd/main.go
new file mode 100644
index 0000000..8040560
--- /dev/null
+++ b/backend/cmd/main.go
@@ -0,0 +1,159 @@
+package main
+
+import (
+ "context"
+ "fmt"
+ "log"
+ "log/slog"
+ "net/http"
+ "os"
+ "os/signal"
+ "time"
+
+ "ibd-trader/internal/analyzer/openai"
+ auth2 "ibd-trader/internal/auth"
+ "ibd-trader/internal/config"
+ "ibd-trader/internal/database"
+ "ibd-trader/internal/ibd"
+ "ibd-trader/internal/keys"
+ "ibd-trader/internal/leader/election"
+ "ibd-trader/internal/leader/manager"
+ "ibd-trader/internal/server2"
+ "ibd-trader/internal/worker"
+
+ "github.com/lmittmann/tint"
+ "github.com/redis/go-redis/v9"
+)
+
+func main() {
+ // Load the config
+ cfg, err := config.New()
+ if err != nil {
+ log.Fatal("Unable to load config: ", err)
+ }
+
+ // Setup slog
+ var level slog.Level
+ if err = level.UnmarshalText([]byte(cfg.Log.Level)); err != nil {
+ log.Fatal("Unable to parse log level: ", err)
+ }
+ var logger *slog.Logger
+ opts := &tint.Options{
+ AddSource: cfg.Log.AddSource,
+ Level: level,
+ NoColor: !cfg.Log.Color,
+ }
+ logger = slog.New(tint.NewHandler(os.Stdout, opts))
+ slog.SetDefault(logger)
+
+ logger.Info(
+ "Starting IBD Trader...",
+ "logger.level", level,
+ )
+
+ // Connect to the database
+ db, err := connectDB(logger, cfg)
+ defer db.Close()
+ if err != nil {
+ log.Fatal("Unable to connect to database: ", err)
+ }
+
+ // Connect to redis
+ redisClient := redis.NewClient(&redis.Options{
+ Addr: cfg.Redis.Addr,
+ Password: cfg.Redis.Password,
+ })
+ defer redisClient.Close()
+
+ // Setup auth
+ auth, err := auth2.New(cfg)
+ if err != nil {
+ log.Fatal("Unable to setup auth: ", err)
+ }
+ _ = auth
+
+ // Setup IBD client
+ client, err := ibd.NewClient(http.DefaultClient, cfg.IBD.APIKey, db, cfg.IBD.ProxyURL)
+ if err != nil {
+ log.Fatal("Unable to setup IBD client: ", err)
+ }
+
+ // Setup analyzer
+ analyzer := openai.NewAnalyzer(openai.WithDefaultConfig(cfg.Analyzer.OpenAI.APIKey))
+ _ = analyzer
+
+ // Setup context w/ signal handling
+ ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
+ defer cancel()
+
+ //// Start the server
+ //go func() {
+ // if err := server.StartServer(ctx, cfg, logger, db, auth, client, redisClient); err != nil {
+ // log.Fatal("Unable to start server: ", err)
+ // }
+ // // Cancel the context when the server stops
+ // cancel()
+ //}()
+
+ // Start the gRPC server
+ go func() {
+ server, err := server2.New(ctx, cfg.Server.Port, db, redisClient)
+ if err != nil {
+ log.Fatal("Unable to create gRPC server: ", err)
+ }
+ if err := server.Serve(ctx); err != nil {
+ slog.ErrorContext(ctx, "Unable to start gRPC server", "error", err)
+ }
+ // Cancel the context when the server stops
+ cancel()
+ }()
+
+ // Start the worker
+ go func() {
+ err := worker.StartWorker(
+ ctx,
+ client,
+ redisClient,
+ db,
+ analyzer,
+ )
+ if err != nil {
+ log.Fatal("Unable to start worker: ", err)
+ }
+ // Cancel the context when the worker stops
+ cancel()
+ }()
+
+ // Start leader election
+ election.RunOrDie(
+ ctx,
+ redisClient,
+ func(ctx context.Context) {
+ m, err := manager.New(ctx, cfg, redisClient, db, client)
+ if err != nil {
+ logger.Error("Unable to create manager", "error", err)
+ return
+ }
+ if err = m.Run(ctx); err != nil {
+ logger.Error("Manager exited with error", "error", err)
+ }
+ },
+ )
+}
+
+func connectDB(logger *slog.Logger, cfg *config.Config) (database.Database, error) {
+ ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
+ defer cancel()
+
+ kms, err := keys.NewGoogleKMS(ctx)
+ if err != nil {
+ return nil, fmt.Errorf("unable to create Google KMS Client: %w", err)
+ }
+
+ db, err := database.New(ctx, logger, cfg.DB.URL, kms, cfg.KMS.GCP.String())
+ if err != nil {
+ return nil, err
+ }
+
+ return db, nil
+}