diff --git a/packages/api/go.mod b/packages/api/go.mod index 3ba2f29491..06f568c053 100644 --- a/packages/api/go.mod +++ b/packages/api/go.mod @@ -114,6 +114,7 @@ require ( github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/edsrzf/mmap-go v1.2.0 // indirect + github.com/exaring/otelpgx v0.9.3 // indirect github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect diff --git a/packages/api/go.sum b/packages/api/go.sum index aa79f3e20e..ebb693abe8 100644 --- a/packages/api/go.sum +++ b/packages/api/go.sum @@ -252,6 +252,8 @@ github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfU github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= github.com/evanw/esbuild v0.24.0 h1:GZ78naTLp7FKr+K7eNuM/SLs5maeiHYRPsTg6kmdsSE= github.com/evanw/esbuild v0.24.0/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48= +github.com/exaring/otelpgx v0.9.3 h1:4yO02tXC7ZJZ+hcqcUkfxblYNCIFGVhpUWI0iw1TzPU= +github.com/exaring/otelpgx v0.9.3/go.mod h1:R5/M5LWsPPBZc1SrRE5e0DiU48bI78C1/GPTWs6I66U= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= diff --git a/packages/api/internal/cfg/model.go b/packages/api/internal/cfg/model.go index e1df80f3fe..feea02823e 100644 --- a/packages/api/internal/cfg/model.go +++ b/packages/api/internal/cfg/model.go @@ -18,7 +18,9 @@ type Config struct { NomadAddress string `env:"NOMAD_ADDRESS" envDefault:"http://localhost:4646"` NomadToken string `env:"NOMAD_TOKEN"` - PostgresConnectionString string `env:"POSTGRES_CONNECTION_STRING,required,notEmpty"` + PostgresConnectionString string `env:"POSTGRES_CONNECTION_STRING,required,notEmpty"` + PostgresMaxConnections int `env:"POSTGRES_MAX_CONNECTIONS" envDefault:"40"` + PostgresMinIdleConnections int `env:"POSTGRES_MIN_IDLE_CONNECTIONS" envDefault:"5"` PosthogAPIKey string `env:"POSTHOG_API_KEY"` diff --git a/packages/api/internal/handlers/store.go b/packages/api/internal/handlers/store.go index 25b90364d1..cb2063c3dc 100644 --- a/packages/api/internal/handlers/store.go +++ b/packages/api/internal/handlers/store.go @@ -2,6 +2,7 @@ package handlers import ( "context" + "database/sql" "errors" "fmt" "net/http" @@ -11,6 +12,7 @@ import ( "github.com/golang-jwt/jwt/v5" "github.com/google/uuid" nomadapi "github.com/hashicorp/nomad/api" + "github.com/jackc/pgx/v5/pgxpool" middleware "github.com/oapi-codegen/gin-middleware" "github.com/redis/go-redis/v9" "go.uber.org/zap" @@ -58,22 +60,15 @@ type APIStore struct { clustersPool *edge.Pool } -func NewAPIStore(ctx context.Context, tel *telemetry.Client, config cfg.Config) *APIStore { +func NewAPIStore(ctx context.Context, tel *telemetry.Client, config cfg.Config, sqlConn *sql.DB, pool *pgxpool.Pool) *APIStore { zap.L().Info("Initializing API store and services") - dbClient, err := db.NewClient(40, 20) - if err != nil { - zap.L().Fatal("Initializing Supabase client", zap.Error(err)) - } - - sqlcDB, err := sqlcdb.NewClient(ctx, sqlcdb.WithMaxConnections(40), sqlcdb.WithMinIdle(5)) - if err != nil { - zap.L().Fatal("Initializing SQLC client", zap.Error(err)) - } + dbClient := db.NewClient(sqlConn) - zap.L().Info("Created database client") + sqlcDB := sqlcdb.NewClient(pool) var clickhouseStore clickhouse.Clickhouse + var err error clickhouseConnectionString := config.ClickhouseConnectionString if clickhouseConnectionString == "" { @@ -216,14 +211,6 @@ func (a *APIStore) Close(ctx context.Context) error { errs = append(errs, fmt.Errorf("closing Template manager client: %w", err)) } - if err := a.sqlcDB.Close(); err != nil { - errs = append(errs, fmt.Errorf("closing sqlc database client: %w", err)) - } - - if err := a.db.Close(); err != nil { - errs = append(errs, fmt.Errorf("closing database client: %w", err)) - } - return errors.Join(errs...) } diff --git a/packages/api/internal/utils/db.go b/packages/api/internal/utils/db.go index f850d41414..448e7b5c5d 100644 --- a/packages/api/internal/utils/db.go +++ b/packages/api/internal/utils/db.go @@ -10,18 +10,7 @@ import ( const trackingTable = "_migrations" -func CheckMigrationVersion(connectionString string, expectedMigration int64) error { - db, err := sql.Open("postgres", connectionString) - if err != nil { - return fmt.Errorf("failed to connect: %w", err) - } - defer func() { - dbErr := db.Close() - if dbErr != nil { - zap.L().Error("Failed to close database connection", zap.Error(dbErr)) - } - }() - +func CheckMigrationVersion(db *sql.DB, expectedMigration int64) error { goose.SetTableName(trackingTable) version, err := goose.GetDBVersion(db) diff --git a/packages/api/main.go b/packages/api/main.go index 402a850a03..741728ba5c 100644 --- a/packages/api/main.go +++ b/packages/api/main.go @@ -35,6 +35,7 @@ import ( metricsMiddleware "github.com/e2b-dev/infra/packages/api/internal/middleware/otel/metrics" tracingMiddleware "github.com/e2b-dev/infra/packages/api/internal/middleware/otel/tracing" "github.com/e2b-dev/infra/packages/api/internal/utils" + "github.com/e2b-dev/infra/packages/shared/pkg/db" "github.com/e2b-dev/infra/packages/shared/pkg/env" l "github.com/e2b-dev/infra/packages/shared/pkg/logger" sbxlogger "github.com/e2b-dev/infra/packages/shared/pkg/logger/sandbox" @@ -278,7 +279,19 @@ func run() int { zap.L().Fatal("Error parsing config", zap.Error(err)) } - err = utils.CheckMigrationVersion(config.PostgresConnectionString, expectedMigration) + dbPool, err := db.NewPool(ctx, + db.WithMaxConnections(config.PostgresMaxConnections), + db.WithMinIdle(config.PostgresMinIdleConnections), + ) + if err != nil { + logger.Fatal("failed to create database pool", zap.Error(err)) + } + defer dbPool.Close() + + dbConn := db.Open(dbPool) + defer dbConn.Close() + + err = utils.CheckMigrationVersion(dbConn, expectedMigration) if err != nil { logger.Fatal("failed to check migration version", zap.Error(err)) } @@ -343,7 +356,7 @@ func run() int { // Create an instance of our handler which satisfies the generated interface // (use the outer context rather than the signal handling // context so it doesn't exit first.) - apiStore := handlers.NewAPIStore(ctx, tel, config) + apiStore := handlers.NewAPIStore(ctx, tel, config, dbConn, dbPool) cleanupFns = append(cleanupFns, apiStore.Close) // pass the signal context so that handlers know when shutdown is happening. diff --git a/packages/db/client/client.go b/packages/db/client/client.go index 4ccc8acdd6..a50ff00369 100644 --- a/packages/db/client/client.go +++ b/packages/db/client/client.go @@ -1,76 +1,18 @@ package client import ( - "context" - - "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" _ "github.com/lib/pq" - "go.uber.org/zap" database "github.com/e2b-dev/infra/packages/db/queries" - "github.com/e2b-dev/infra/packages/shared/pkg/utils" ) type Client struct { *database.Queries - - conn *pgxpool.Pool -} - -type Option func(config *pgxpool.Config) - -func WithMaxConnections(maxConns int32) Option { - return func(config *pgxpool.Config) { - config.MaxConns = maxConns - } } -func WithMinIdle(minIdle int32) Option { - return func(config *pgxpool.Config) { - config.MinIdleConns = minIdle - } -} - -func NewClient(ctx context.Context, options ...Option) (*Client, error) { - databaseURL := utils.RequiredEnv("POSTGRES_CONNECTION_STRING", "Postgres connection string") - - // Parse the connection pool configuration - config, err := pgxpool.ParseConfig(databaseURL) - if err != nil { - zap.L().Error("Unable to parse database URL", zap.Error(err)) - - return nil, err - } - - // Set the default number of connections - for _, option := range options { - option(config) - } - - // Create the connection pool - pool, err := pgxpool.NewWithConfig(ctx, config) - if err != nil { - zap.L().Error("Unable to create connection pool", zap.Error(err)) - } - +func NewClient(pool *pgxpool.Pool) *Client { queries := database.New(pool) - return &Client{Queries: queries, conn: pool}, nil -} - -func (db *Client) Close() error { - db.conn.Close() - return nil -} - -// WithTx runs the given function in a transaction. -func (db *Client) WithTx(ctx context.Context) (*Client, pgx.Tx, error) { - tx, err := db.conn.BeginTx(ctx, pgx.TxOptions{}) - if err != nil { - return nil, nil, err - } - - client := &Client{Queries: db.Queries.WithTx(tx), conn: db.conn} - return client, tx, nil + return &Client{Queries: queries} } diff --git a/packages/db/go.mod b/packages/db/go.mod index ef00a92d6e..36e84cda78 100644 --- a/packages/db/go.mod +++ b/packages/db/go.mod @@ -10,17 +10,17 @@ tool ( ) require ( - github.com/e2b-dev/infra/packages/shared v0.0.0-20250324174051-3fb806938dc1 github.com/google/uuid v1.6.0 github.com/jackc/pgx/v5 v5.7.4 github.com/lib/pq v1.10.9 github.com/pressly/goose/v3 v3.24.2 - go.uber.org/zap v1.27.0 ) require ( cel.dev/expr v0.24.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect github.com/ClickHouse/ch-go v0.66.1 // indirect github.com/ClickHouse/clickhouse-go/v2 v2.37.2 // indirect github.com/andybalholm/brotli v1.1.1 // indirect @@ -48,6 +48,7 @@ require ( github.com/joho/godotenv v1.5.1 // indirect github.com/jonboulle/clockwork v0.5.0 // indirect github.com/klauspost/compress v1.18.0 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mfridman/interpolate v0.0.2 // indirect github.com/mfridman/xflag v0.1.0 // indirect @@ -60,9 +61,11 @@ require ( github.com/pingcap/failpoint v0.0.0-20240528011301-b51a646c7c86 // indirect github.com/pingcap/log v1.1.0 // indirect github.com/pingcap/tidb/pkg/parser v0.0.0-20250324122243-d51e00e5bbf0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/procfs v0.16.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/riza-io/grpc-go v0.2.0 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/sethvargo/go-retry v0.3.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect @@ -78,14 +81,16 @@ require ( github.com/ydb-platform/ydb-go-genproto v0.0.0-20241112172322-ea1f63298f77 // indirect github.com/ydb-platform/ydb-go-sdk/v3 v3.104.7 // indirect github.com/ziutek/mymysql v1.5.4 // indirect + go.opentelemetry.io/auto/sdk v1.2.0 // indirect go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect go.opentelemetry.io/otel/trace v1.38.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.5.2 // indirect go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.42.0 // indirect golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b // indirect - golang.org/x/mod v0.27.0 // indirect golang.org/x/net v0.44.0 // indirect golang.org/x/sync v0.17.0 // indirect golang.org/x/sys v0.36.0 // indirect diff --git a/packages/db/go.sum b/packages/db/go.sum index 64ebb534dd..57c6774eeb 100644 --- a/packages/db/go.sum +++ b/packages/db/go.sum @@ -39,6 +39,7 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE= github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cubicdaiya/gonp v1.0.4 h1:ky2uIAJh81WiLcGKBVD5R7KsM/36W6IqqTy6Bo6rGws= github.com/cubicdaiya/gonp v1.0.4/go.mod h1:iWGuP/7+JVTn02OWhRemVbMmG1DOUnmrGTYYACpOI0I= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -180,6 +181,7 @@ github.com/pingcap/tidb/pkg/parser v0.0.0-20250324122243-d51e00e5bbf0 h1:W3rpAI3 github.com/pingcap/tidb/pkg/parser v0.0.0-20250324122243-d51e00e5bbf0/go.mod h1:+8feuexTKcXHZF/dkDfvCwEyBAmgb4paFc3/WeYV2eE= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -198,6 +200,7 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq github.com/riza-io/grpc-go v0.2.0 h1:2HxQKFVE7VuYstcJ8zqpN84VnAoJ4dCL6YFhJewNcHQ= github.com/riza-io/grpc-go v0.2.0/go.mod h1:2bDvR9KkKC3KhtlSHfR3dAXjUMT86kg4UfWFyVGWqi8= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= diff --git a/packages/docker-reverse-proxy/go.mod b/packages/docker-reverse-proxy/go.mod index fb68499b38..c60d4f2e6a 100644 --- a/packages/docker-reverse-proxy/go.mod +++ b/packages/docker-reverse-proxy/go.mod @@ -15,14 +15,28 @@ require ( github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/dchest/uniuri v1.2.0 // indirect + github.com/exaring/otelpgx v0.9.3 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/inflect v0.21.0 // indirect github.com/go-test/deep v1.0.8 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl/v2 v2.19.1 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/jackc/pgx/v5 v5.7.4 // indirect + github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/lib/pq v1.10.9 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/zclconf/go-cty v1.14.1 // indirect + go.opentelemetry.io/auto/sdk v1.2.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.42.0 // indirect golang.org/x/mod v0.27.0 // indirect golang.org/x/sync v0.17.0 // indirect golang.org/x/text v0.29.0 // indirect diff --git a/packages/docker-reverse-proxy/go.sum b/packages/docker-reverse-proxy/go.sum index 29b742df6d..ee12f8df17 100644 --- a/packages/docker-reverse-proxy/go.sum +++ b/packages/docker-reverse-proxy/go.sum @@ -8,10 +8,18 @@ github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7l github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dchest/uniuri v1.2.0 h1:koIcOUdrTIivZgSLhHQvKgqdWZq5d7KdMEWF1Ud6+5g= github.com/dchest/uniuri v1.2.0/go.mod h1:fSzm4SLHzNZvWLvWJew423PhAzkpNQYq+uNLq4kxhkY= +github.com/exaring/otelpgx v0.9.3 h1:4yO02tXC7ZJZ+hcqcUkfxblYNCIFGVhpUWI0iw1TzPU= +github.com/exaring/otelpgx v0.9.3/go.mod h1:R5/M5LWsPPBZc1SrRE5e0DiU48bI78C1/GPTWs6I66U= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/inflect v0.21.0 h1:FoBjBTQEcbg2cJUWX6uwL9OyIW8eqc9k4KhN4lfbeYk= github.com/go-openapi/inflect v0.21.0/go.mod h1:INezMuUu7SJQc2AyR3WO0DqqYUJSj8Kb4hBd7WtjlAw= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= @@ -22,6 +30,14 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/hcl/v2 v2.19.1 h1://i05Jqznmb2EXqa39Nsvyan2o5XyMowW5fnCKW5RPI= github.com/hashicorp/hcl/v2 v2.19.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.7.4 h1:9wKznZrhWa2QiHL+NjTSPP6yjl3451BX3imWDnokYlg= +github.com/jackc/pgx/v5 v5.7.4/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jellydator/ttlcache/v3 v3.4.0 h1:YS4P125qQS0tNhtL6aeYkheEaB/m8HCqdMMP4mnWdTY= github.com/jellydator/ttlcache/v3 v3.4.0/go.mod h1:Hw9EgjymziQD3yGsQdf1FqFdpp7YjFMd4Srg5EJlgD4= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -36,23 +52,47 @@ github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/zclconf/go-cty v1.14.1 h1:t9fyA35fwjjUMcmL5hLER+e/rEPqrbCK1/OSE4SI9KA= github.com/zclconf/go-cty v1.14.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +go.opentelemetry.io/auto/sdk v1.2.0 h1:YpRtUFjvhSymycLS2T81lT6IGhcUP+LUPtv0iv1N8bM= +go.opentelemetry.io/auto/sdk v1.2.0/go.mod h1:1deq2zL7rwjwC8mR7XgY2N+tlIl6pjmEUoLDENMEzwk= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/packages/docker-reverse-proxy/internal/cache/auth.go b/packages/docker-reverse-proxy/internal/cache/auth.go index ef95fe52fb..53dffd2f5a 100644 --- a/packages/docker-reverse-proxy/internal/cache/auth.go +++ b/packages/docker-reverse-proxy/internal/cache/auth.go @@ -31,6 +31,8 @@ func New() *AuthCache { return &AuthCache{cache: cache} } +var ErrNotInCache = fmt.Errorf("creds not found in cache") + // Get returns the auth token for the given teamID and e2bToken. func (c *AuthCache) Get(e2bToken string) (*AccessTokenData, error) { if e2bToken == "" { @@ -40,7 +42,7 @@ func (c *AuthCache) Get(e2bToken string) (*AccessTokenData, error) { item := c.cache.Get(e2bToken) if item == nil { - return nil, fmt.Errorf("creds for '%s' not found in cache", e2bToken) + return nil, ErrNotInCache } return item.Value(), nil diff --git a/packages/docker-reverse-proxy/internal/handlers/store.go b/packages/docker-reverse-proxy/internal/handlers/store.go index 50d33344aa..bb62d7e646 100644 --- a/packages/docker-reverse-proxy/internal/handlers/store.go +++ b/packages/docker-reverse-proxy/internal/handlers/store.go @@ -1,6 +1,7 @@ package handlers import ( + "database/sql" "fmt" "io" "log" @@ -19,12 +20,9 @@ type APIStore struct { proxy *httputil.ReverseProxy } -func NewStore() *APIStore { +func NewStore(dbConn *sql.DB) *APIStore { authCache := cache.New() - database, err := db.NewClient(3, 2) - if err != nil { - log.Fatal(err) - } + database := db.NewClient(dbConn) targetUrl := &url.URL{ Scheme: "https", diff --git a/packages/docker-reverse-proxy/main.go b/packages/docker-reverse-proxy/main.go index e92b1924f2..fc424b688f 100644 --- a/packages/docker-reverse-proxy/main.go +++ b/packages/docker-reverse-proxy/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "flag" "fmt" "log" @@ -11,14 +12,21 @@ import ( "github.com/e2b-dev/infra/packages/docker-reverse-proxy/internal/constants" "github.com/e2b-dev/infra/packages/docker-reverse-proxy/internal/handlers" "github.com/e2b-dev/infra/packages/docker-reverse-proxy/internal/utils" + "github.com/e2b-dev/infra/packages/shared/pkg/db" ) var commitSHA string func main() { + if err := run(); err != nil { + log.Fatal(err) + } +} + +func run() error { err := constants.CheckRequired() if err != nil { - log.Fatal(err) + return fmt.Errorf("required environment variables are not set: %w", err) } port := flag.Int("port", 5000, "Port for test HTTP server") @@ -26,7 +34,18 @@ func main() { log.Println("Starting docker reverse proxy", "commit", commitSHA) - store := handlers.NewStore() + ctx := context.Background() + + dbPool, err := db.NewPool(ctx, db.WithMinIdle(1), db.WithMaxConnections(1)) + if err != nil { + return fmt.Errorf("failed to create db pool: %w", err) + } + defer dbPool.Close() + + dbConn := db.Open(dbPool) + defer dbConn.Close() + + store := handlers.NewStore(dbConn) // https://distribution.github.io/distribution/spec/api/ http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { @@ -88,5 +107,10 @@ func main() { }) log.Printf("Starting server on port: %d\n", *port) - log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", strconv.Itoa(*port)), nil)) + + if err := http.ListenAndServe(fmt.Sprintf(":%s", strconv.Itoa(*port)), nil); err != nil { + return fmt.Errorf("failed to start server: %w", err) + } + + return nil } diff --git a/packages/local-dev/go.mod b/packages/local-dev/go.mod index a299592014..eb66af4f6f 100644 --- a/packages/local-dev/go.mod +++ b/packages/local-dev/go.mod @@ -37,6 +37,7 @@ require ( github.com/docker/go-connections v0.6.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/ebitengine/purego v0.8.4 // indirect + github.com/exaring/otelpgx v0.9.3 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect diff --git a/packages/local-dev/go.sum b/packages/local-dev/go.sum index 7ba61867cf..9193d6cc6c 100644 --- a/packages/local-dev/go.sum +++ b/packages/local-dev/go.sum @@ -48,6 +48,8 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4 github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw= github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/exaring/otelpgx v0.9.3 h1:4yO02tXC7ZJZ+hcqcUkfxblYNCIFGVhpUWI0iw1TzPU= +github.com/exaring/otelpgx v0.9.3/go.mod h1:R5/M5LWsPPBZc1SrRE5e0DiU48bI78C1/GPTWs6I66U= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= diff --git a/packages/local-dev/seed-local-database.go b/packages/local-dev/seed-local-database.go index b5461b2a53..4617896556 100644 --- a/packages/local-dev/seed-local-database.go +++ b/packages/local-dev/seed-local-database.go @@ -45,37 +45,37 @@ func run(ctx context.Context) error { } } - // init database - database, err := db.NewClient(1, 0) + dbPool, err := db.NewPool(ctx, db.WithMaxConnections(1), db.WithMinIdle(0)) if err != nil { - return fmt.Errorf("failed to initialize db: %w", err) + return fmt.Errorf("failed to create db pool: %w", err) } - defer database.Close() + defer dbPool.Close() - sqlcDB, err := client.NewClient(ctx) - if err != nil { - return fmt.Errorf("failed to connect to database: %w", err) - } - defer sqlcDB.Close() + dbConn := db.Open(dbPool) + defer dbConn.Close() + + // init database + dbClient := db.NewClient(dbConn) + sqlcDB := client.NewClient(dbPool) // create user - user, err := upsertUser(ctx, database) + user, err := upsertUser(ctx, dbClient) if err != nil { return fmt.Errorf("failed to upsert user: %w", err) } // create team - team, err := upsertTeam(ctx, database) + team, err := upsertTeam(ctx, dbClient) if err != nil { return fmt.Errorf("failed to upsert team: %w", err) } - if err = ensureUserIsOnTeam(ctx, database, user, team); err != nil { + if err = ensureUserIsOnTeam(ctx, dbClient, user, team); err != nil { return fmt.Errorf("failed to ensure user is on team: %w", err) } // create user token - if err = upsertUserToken(ctx, database, user, keys.AccessTokenPrefix, userTokenValue); err != nil { + if err = upsertUserToken(ctx, dbClient, user, keys.AccessTokenPrefix, userTokenValue); err != nil { return fmt.Errorf("failed to upsert token: %w", err) } diff --git a/packages/shared/go.mod b/packages/shared/go.mod index adea0b4ce1..5ef1f015e1 100644 --- a/packages/shared/go.mod +++ b/packages/shared/go.mod @@ -32,6 +32,7 @@ require ( github.com/bits-and-blooms/bitset v1.22.0 github.com/dchest/uniuri v1.2.0 github.com/e2b-dev/infra/packages/db v0.0.0-20251013083250-eb6cd250d671 + github.com/exaring/otelpgx v0.9.3 github.com/getkin/kin-openapi v0.132.0 github.com/gin-gonic/gin v1.10.1 github.com/go-openapi/errors v0.22.0 @@ -46,6 +47,7 @@ require ( github.com/grafana/loki v0.0.0-20250609195516-7b805ba7c843 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 github.com/hashicorp/go-retryablehttp v0.7.7 + github.com/jackc/pgx/v5 v5.7.4 github.com/jellydator/ttlcache/v3 v3.4.0 github.com/launchdarkly/go-sdk-common/v3 v3.3.0 github.com/launchdarkly/go-server-sdk/v7 v7.13.0 @@ -212,7 +214,6 @@ require ( github.com/imdario/mergo v0.3.16 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/pgx/v5 v5.7.4 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jessevdk/go-flags v1.5.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect diff --git a/packages/shared/go.sum b/packages/shared/go.sum index 210228b744..1a88936570 100644 --- a/packages/shared/go.sum +++ b/packages/shared/go.sum @@ -289,6 +289,8 @@ github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJP github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/exaring/otelpgx v0.9.3 h1:4yO02tXC7ZJZ+hcqcUkfxblYNCIFGVhpUWI0iw1TzPU= +github.com/exaring/otelpgx v0.9.3/go.mod h1:R5/M5LWsPPBZc1SrRE5e0DiU48bI78C1/GPTWs6I66U= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= diff --git a/packages/shared/pkg/db/client.go b/packages/shared/pkg/db/client.go index 28fcf1f206..7fb493ae78 100644 --- a/packages/shared/pkg/db/client.go +++ b/packages/shared/pkg/db/client.go @@ -1,12 +1,10 @@ package db import ( - "fmt" - "os" - "time" + "database/sql" "entgo.io/ent/dialect" - "entgo.io/ent/dialect/sql" + entsql "entgo.io/ent/dialect/sql" _ "github.com/lib/pq" "github.com/e2b-dev/infra/packages/shared/pkg/models" @@ -16,26 +14,12 @@ type DB struct { Client *models.Client } -func NewClient(maxConns, maxIdle int) (*DB, error) { - databaseURL := os.Getenv("POSTGRES_CONNECTION_STRING") - if databaseURL == "" { - return nil, fmt.Errorf("database URL is empty") - } - - drv, err := sql.Open(dialect.Postgres, databaseURL) - if err != nil { - return nil, err - } - - // Get the underlying sql.DB object of the driver. - db := drv.DB() - db.SetMaxOpenConns(maxConns) - db.SetMaxIdleConns(maxIdle) - db.SetConnMaxLifetime(time.Minute * 30) +func NewClient(conn *sql.DB) *DB { + drv := entsql.OpenDB(dialect.Postgres, conn) client := models.NewClient(models.Driver(drv)) - return &DB{Client: client}, nil + return &DB{Client: client} } func (db *DB) Close() error { diff --git a/packages/shared/pkg/db/conn.go b/packages/shared/pkg/db/conn.go new file mode 100644 index 0000000000..1fd5594818 --- /dev/null +++ b/packages/shared/pkg/db/conn.go @@ -0,0 +1,19 @@ +package db + +import ( + "database/sql" + "time" + + "github.com/jackc/pgx/v5/pgxpool" + "github.com/jackc/pgx/v5/stdlib" +) + +func Open(pool *pgxpool.Pool) *sql.DB { + connector := stdlib.GetPoolConnector(pool) + db := sql.OpenDB(connector) + + db.SetMaxIdleConns(0) // let the pool manage the number of connections + db.SetConnMaxLifetime(time.Minute * 30) + + return db +} diff --git a/packages/shared/pkg/db/pool.go b/packages/shared/pkg/db/pool.go new file mode 100644 index 0000000000..7f46ba2522 --- /dev/null +++ b/packages/shared/pkg/db/pool.go @@ -0,0 +1,59 @@ +package db + +import ( + "context" + "fmt" + "os" + + "github.com/exaring/otelpgx" + "github.com/jackc/pgx/v5/pgxpool" + "go.uber.org/zap" +) + +type PoolOption func(config *pgxpool.Config) + +func WithMaxConnections(maxConns int) PoolOption { + return func(config *pgxpool.Config) { + config.MaxConns = int32(maxConns) + } +} + +func WithMinIdle(minIdle int) PoolOption { + return func(config *pgxpool.Config) { + config.MinIdleConns = int32(minIdle) + } +} + +func NewPool(ctx context.Context, options ...PoolOption) (*pgxpool.Pool, error) { + databaseURL := os.Getenv("POSTGRES_CONNECTION_STRING") + if databaseURL == "" { + return nil, fmt.Errorf("POSTGRES_CONNECTION_STRING is not set") + } + + config, err := pgxpool.ParseConfig(databaseURL) + if err != nil { + zap.L().Error("Unable to parse database URL", zap.Error(err)) + + return nil, fmt.Errorf("failed to parse database URL: %w", err) + } + + for _, option := range options { + option(config) + } + + // expose otel traces + config.ConnConfig.Tracer = otelpgx.NewTracer() + + // Create the connection pool + pool, err := pgxpool.NewWithConfig(ctx, config) + if err != nil { + return nil, fmt.Errorf("failed to create connection pool: %w", err) + } + + // expose otel metrics + if err := otelpgx.RecordStats(pool); err != nil { + return nil, fmt.Errorf("failed to record stats: %w", err) + } + + return pool, nil +} diff --git a/packages/shared/scripts/seed/postgres/seed-db.go b/packages/shared/scripts/seed/postgres/seed-db.go index 066fe9c051..105ad2bfd3 100644 --- a/packages/shared/scripts/seed/postgres/seed-db.go +++ b/packages/shared/scripts/seed/postgres/seed-db.go @@ -25,17 +25,19 @@ func main() { ctx := context.Background() hasher := keys.NewSHA256Hashing() - database, err := db.NewClient(1, 1) + dbPool, err := db.NewPool(ctx) if err != nil { panic(err) } + defer dbPool.Close() + + dbConn := db.Open(dbPool) + defer dbConn.Close() + + database := db.NewClient(dbConn) defer database.Close() - sqlcDB, err := sqlcdb.NewClient(ctx) - if err != nil { - panic(err) - } - defer sqlcDB.Close() + sqlcDB := sqlcdb.NewClient(dbPool) count, err := database.Client.Team.Query().Count(ctx) if err != nil { diff --git a/tests/integration/go.mod b/tests/integration/go.mod index 70f44c49cb..a12335ce2f 100644 --- a/tests/integration/go.mod +++ b/tests/integration/go.mod @@ -42,6 +42,7 @@ require ( github.com/dchest/uniuri v1.2.0 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect + github.com/exaring/otelpgx v0.9.3 // indirect github.com/fatih/color v1.18.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/getkin/kin-openapi v0.132.0 // indirect diff --git a/tests/integration/go.sum b/tests/integration/go.sum index 8df788c657..b53e67b2bf 100644 --- a/tests/integration/go.sum +++ b/tests/integration/go.sum @@ -38,6 +38,8 @@ github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Z github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= +github.com/exaring/otelpgx v0.9.3 h1:4yO02tXC7ZJZ+hcqcUkfxblYNCIFGVhpUWI0iw1TzPU= +github.com/exaring/otelpgx v0.9.3/go.mod h1:R5/M5LWsPPBZc1SrRE5e0DiU48bI78C1/GPTWs6I66U= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= diff --git a/tests/integration/internal/setup/db_client.go b/tests/integration/internal/setup/db_client.go index 357d2f2cd1..a5eba1afd6 100644 --- a/tests/integration/internal/setup/db_client.go +++ b/tests/integration/internal/setup/db_client.go @@ -11,12 +11,14 @@ import ( func GetTestDBClient(tb testing.TB) *db.DB { tb.Helper() - database, err := db.NewClient(1, 1) + dbPool, err := db.NewPool(tb.Context()) require.NoError(tb, err) + tb.Cleanup(func() { dbPool.Close() }) - tb.Cleanup(func() { - database.Close() - }) + dbConn := db.Open(dbPool) + + database := db.NewClient(dbConn) + tb.Cleanup(func() { database.Close() }) return database } diff --git a/tests/integration/seed.go b/tests/integration/seed.go index 6b533c8733..b4cf939691 100644 --- a/tests/integration/seed.go +++ b/tests/integration/seed.go @@ -40,25 +40,20 @@ func main() { } func run(ctx context.Context) int { - connectionString := os.Getenv("POSTGRES_CONNECTION_STRING") - if connectionString == "" { - log.Printf("POSTGRES_CONNECTION_STRING is not set") - return 1 - } - - database, err := db.NewClient(1, 1) + dbPool, err := db.NewPool(ctx) if err != nil { log.Printf("Failed to connect to database: %v", err) return 1 } + defer dbPool.Close() + + dbConn := db.Open(dbPool) + defer dbConn.Close() + + database := db.NewClient(dbConn) defer database.Close() - sqlcDB, err := client.NewClient(ctx) - if err != nil { - log.Printf("Failed to connect to database: %v", err) - return 1 - } - defer sqlcDB.Close() + sqlcDB := client.NewClient(dbPool) data := SeedData{ AccessToken: os.Getenv("TESTS_E2B_ACCESS_TOKEN"),