intial commit
This commit is contained in:
185
db/connect copy.go
Normal file
185
db/connect copy.go
Normal file
@@ -0,0 +1,185 @@
|
||||
package db
|
||||
|
||||
// import (
|
||||
// "fmt"
|
||||
// "log"
|
||||
// "nearle/utils"
|
||||
// "time"
|
||||
|
||||
// "gorm.io/driver/mysql"
|
||||
// "gorm.io/gorm"
|
||||
// )
|
||||
|
||||
// var DB *gorm.DB
|
||||
|
||||
// var (
|
||||
// DB_DEV *gorm.DB
|
||||
// DB_LIVE *gorm.DB
|
||||
// )
|
||||
|
||||
// func DevConnect() {
|
||||
|
||||
// var DBname string
|
||||
// var Username string
|
||||
// var Password string
|
||||
// var Host string
|
||||
// var Port string
|
||||
|
||||
// var err error
|
||||
|
||||
// Port, DBname, Password, Username, Host, _, _ = utils.DevConfig()
|
||||
|
||||
// dsn := Username + ":" + Password + "@tcp" + "(" + Host + ":" + Port + ")/" + DBname + "?" + "parseTime=true&loc=Local"
|
||||
|
||||
// DB_DEV, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
// if err != nil {
|
||||
// log.Fatal("❌ Could not connect to Dev database:", err)
|
||||
// }
|
||||
// setupDB(DB_DEV)
|
||||
// fmt.Println("✅ Connected to Dev Database")
|
||||
|
||||
// // var DBname string
|
||||
// // var Username string
|
||||
// // var Password string
|
||||
// // var Host string
|
||||
// // var Port string
|
||||
|
||||
// // Port, DBname, Password, Username, Host, _, _ = utils.DevConfig()
|
||||
|
||||
// // dsn := Username + ":" + Password + "@tcp" + "(" + Host + ":" + Port + ")/" + DBname + "?" + "parseTime=true&loc=Local"
|
||||
|
||||
// // for i := 0; i < 5; i++ {
|
||||
// // db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
// // if err == nil {
|
||||
// // sqlDB, _ := db.DB()
|
||||
// // sqlDB.SetMaxIdleConns(100)
|
||||
// // sqlDB.SetMaxOpenConns(1000)
|
||||
// // sqlDB.SetConnMaxLifetime(time.Hour)
|
||||
// // err = sqlDB.Ping()
|
||||
// // if err == nil {
|
||||
// // log.Println("Successfully connected to the database.")
|
||||
// // DB = db
|
||||
// // return
|
||||
// // }
|
||||
// // }
|
||||
// // log.Printf("Failed to connect to the database, retrying... (%d/5)\n", i+1)
|
||||
// // time.Sleep(2 * time.Second)
|
||||
// // }
|
||||
// // // log.Fatal("Could not connect to the database:", err)
|
||||
|
||||
// // // database, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
// // // if err != nil {
|
||||
// // // panic("Could not connect to the database")
|
||||
// // // }
|
||||
|
||||
// }
|
||||
|
||||
// func setupDB(database *gorm.DB) {
|
||||
// sqlDB, err := database.DB()
|
||||
// if err != nil {
|
||||
// log.Fatal("❌ Failed to get DB from GORM:", err)
|
||||
// }
|
||||
// sqlDB.SetMaxIdleConns(10)
|
||||
// sqlDB.SetMaxOpenConns(100)
|
||||
// sqlDB.SetConnMaxLifetime(30 * time.Minute)
|
||||
// }
|
||||
|
||||
// // func LiveConnect() {
|
||||
|
||||
// // var DBname string
|
||||
// // var Username string
|
||||
// // var Password string
|
||||
// // var Host string
|
||||
// // var Port string
|
||||
|
||||
// // Port, DBname, Password, Username, Host, _, _ = utils.DevConfig()
|
||||
|
||||
// // dsn := Username + ":" + Password + "@tcp" + "(" + Host + ":" + Port + ")/" + DBname + "?" + "parseTime=true&loc=Local"
|
||||
|
||||
// // for i := 0; i < 5; i++ {
|
||||
// // db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
// // if err != nil {
|
||||
// // log.Printf("Failed to connect to the database, retrying... (%d/5)\n", i+1)
|
||||
// // log.Println("Error:", err)
|
||||
// // time.Sleep(2 * time.Second)
|
||||
// // continue
|
||||
// // }
|
||||
|
||||
// // sqlDB, err := db.DB()
|
||||
// // if err != nil {
|
||||
// // log.Println("Failed to get DB from GORM:", err)
|
||||
// // time.Sleep(2 * time.Second)
|
||||
// // continue
|
||||
// // }
|
||||
|
||||
// // sqlDB.SetMaxIdleConns(10)
|
||||
// // sqlDB.SetMaxOpenConns(100)
|
||||
// // sqlDB.SetConnMaxLifetime(time.Hour)
|
||||
|
||||
// // if err = sqlDB.Ping(); err != nil {
|
||||
// // log.Printf("Failed to ping database, retrying... (%d/5)\n", i+1)
|
||||
// // log.Println("Error:", err)
|
||||
// // time.Sleep(2 * time.Second)
|
||||
// // continue
|
||||
// // }
|
||||
|
||||
// // log.Println("Successfully connected to the database.")
|
||||
// // DB = db
|
||||
// // return
|
||||
// // }
|
||||
|
||||
// // log.Fatal("Could not connect to the database after multiple attempts.")
|
||||
|
||||
// // }
|
||||
|
||||
// func LiveConnect() {
|
||||
|
||||
// var DBname string
|
||||
// var Username string
|
||||
// var Password string
|
||||
// var Host string
|
||||
// var Port string
|
||||
|
||||
// Port, DBname, Password, Username, Host, _, _ = utils.LiveConfig()
|
||||
|
||||
// // dsn := "zqbuvyrhhf:Package%40%123#@tcp(165.232.178.78:3306)/dbname?parseTime=true"
|
||||
|
||||
// dsn := Username + ":" + Password + "@tcp" + "(" + Host + ":" + Port + ")/" + DBname + "?" + "parseTime=true&loc=Local"
|
||||
|
||||
// //database, err := sql.Open("mysql", dsn)
|
||||
|
||||
// database, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
// if err != nil {
|
||||
// panic("Could not connect to the database")
|
||||
// }
|
||||
|
||||
// sqlDB, err := database.DB()
|
||||
// if err != nil {
|
||||
// log.Println("Failed to get DB from GORM:", err)
|
||||
// panic("Could not connect to the database")
|
||||
|
||||
// }
|
||||
// sqlDB.SetMaxIdleConns(100)
|
||||
// sqlDB.SetMaxOpenConns(1000)
|
||||
// sqlDB.SetConnMaxLifetime(time.Hour)
|
||||
|
||||
// if err = sqlDB.Ping(); err != nil {
|
||||
// log.Println("Error:", err)
|
||||
// panic("Could not connect to the database")
|
||||
// }
|
||||
|
||||
// fmt.Println("Live Database Connected Successfully")
|
||||
// DB = database
|
||||
|
||||
// }
|
||||
|
||||
// func CloseDB() {
|
||||
// sqlDB, err := DB.DB()
|
||||
// if err != nil {
|
||||
// log.Println("Error retrieving sql.DB from GORM:", err)
|
||||
// return
|
||||
// }
|
||||
// fmt.Println("Connection closed Successfully")
|
||||
// sqlDB.Close() // This will close the connection pool
|
||||
|
||||
// }
|
||||
221
db/connect.go
Normal file
221
db/connect.go
Normal file
@@ -0,0 +1,221 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"nearle/utils"
|
||||
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
var (
|
||||
DB *gorm.DB
|
||||
)
|
||||
|
||||
// --------------------
|
||||
// DATABASE CONNECTION
|
||||
// --------------------
|
||||
|
||||
func Connect() {
|
||||
dsn := fmt.Sprintf(
|
||||
"host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Kolkata",
|
||||
mustEnv("DB_HOST"),
|
||||
mustEnv("DB_USER"),
|
||||
mustEnv("DB_PASSWORD"),
|
||||
mustEnv("DB_NAME"),
|
||||
getEnv("DB_PORT", "5432"),
|
||||
)
|
||||
|
||||
var err error
|
||||
maxRetries := 10
|
||||
backoff := 2 * time.Second
|
||||
|
||||
for i := 1; i <= maxRetries; i++ {
|
||||
utils.Logger.Infow("Connecting to database", "attempt", i)
|
||||
|
||||
DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Error),
|
||||
})
|
||||
|
||||
if err == nil {
|
||||
sqlDB, dbErr := DB.DB()
|
||||
if dbErr == nil {
|
||||
|
||||
// 🔥 Ping with timeout (important)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if pingErr := sqlDB.PingContext(ctx); pingErr == nil {
|
||||
setupDB(DB)
|
||||
|
||||
utils.Logger.Infow("✅ Database connected successfully")
|
||||
|
||||
// Start background health check
|
||||
startDBHealthCheck(sqlDB)
|
||||
|
||||
return
|
||||
} else {
|
||||
err = pingErr
|
||||
}
|
||||
} else {
|
||||
err = dbErr
|
||||
}
|
||||
}
|
||||
|
||||
utils.Logger.Errorw("❌ DB connection failed", "attempt", i, "error", err)
|
||||
time.Sleep(backoff)
|
||||
backoff *= 2
|
||||
}
|
||||
|
||||
utils.Logger.Fatalw("☢️ CRITICAL: DB connection failed after retries")
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// CONNECTION POOLING
|
||||
// --------------------
|
||||
|
||||
func setupDB(database *gorm.DB) {
|
||||
sqlDB, err := database.DB()
|
||||
if err != nil {
|
||||
utils.Logger.Errorw("Failed to get sql.DB", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 🔥 K8s SAFE CONFIG
|
||||
sqlDB.SetMaxOpenConns(30) // total open connections
|
||||
sqlDB.SetMaxIdleConns(5) // idle connections
|
||||
sqlDB.SetConnMaxLifetime(5 * time.Minute) // avoid stale connections
|
||||
sqlDB.SetConnMaxIdleTime(2 * time.Minute)
|
||||
|
||||
stats := sqlDB.Stats()
|
||||
utils.Logger.Infow("DB Pool configured",
|
||||
"MaxOpen", stats.MaxOpenConnections,
|
||||
)
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// DB HEALTH CHECK
|
||||
// --------------------
|
||||
|
||||
func startDBHealthCheck(sqlDB *sql.DB) {
|
||||
go func() {
|
||||
for {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
|
||||
err := sqlDB.PingContext(ctx)
|
||||
cancel()
|
||||
|
||||
if err != nil {
|
||||
utils.Logger.Errorw("❌ DB connection lost", "error", err)
|
||||
}
|
||||
|
||||
time.Sleep(30 * time.Second)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// CLOSE DB
|
||||
// --------------------
|
||||
|
||||
func CloseDB() {
|
||||
if DB == nil {
|
||||
return
|
||||
}
|
||||
|
||||
sqlDB, err := DB.DB()
|
||||
if err != nil {
|
||||
utils.Logger.Errorw("Error retrieving sql.DB", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
utils.Logger.Infow("Closing DB connection")
|
||||
sqlDB.Close()
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// ENV HELPERS
|
||||
// --------------------
|
||||
|
||||
func mustEnv(key string) string {
|
||||
val := os.Getenv(key)
|
||||
if val == "" {
|
||||
utils.Logger.Warnw("Missing env variable", "key", key)
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func getEnv(key, fallback string) string {
|
||||
if val := os.Getenv(key); val != "" {
|
||||
return val
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// REDIS CONNECTION
|
||||
// --------------------
|
||||
|
||||
var Rdb *redis.Client
|
||||
var Ctx = context.Background()
|
||||
|
||||
func InitRedis() {
|
||||
redisHost := getEnv("REDIS_HOST", "66.116.226.255") // ✅ FIXED IP
|
||||
redisPort := getEnv("REDIS_PORT", "6379")
|
||||
|
||||
addr := fmt.Sprintf("%s:%s", redisHost, redisPort)
|
||||
|
||||
Rdb = redis.NewClient(&redis.Options{
|
||||
Addr: addr,
|
||||
Username: "default",
|
||||
Password: "Package@324969#",
|
||||
DB: 0,
|
||||
|
||||
// ✅ TIMEOUTS (VERY IMPORTANT)
|
||||
DialTimeout: 10 * time.Second,
|
||||
ReadTimeout: 10 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
|
||||
// ✅ POOL
|
||||
PoolSize: 50,
|
||||
MinIdleConns: 10,
|
||||
|
||||
// ✅ RETRIES
|
||||
MaxRetries: 3,
|
||||
MinRetryBackoff: 500 * time.Millisecond,
|
||||
MaxRetryBackoff: 2 * time.Second,
|
||||
})
|
||||
|
||||
maxRetries := 5
|
||||
backoff := 1 * time.Second
|
||||
|
||||
for i := 1; i <= maxRetries; i++ {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
|
||||
_, err := Rdb.Ping(ctx).Result()
|
||||
cancel()
|
||||
|
||||
if err == nil {
|
||||
utils.Logger.Infow("✅ Redis connected successfully", "addr", addr)
|
||||
return
|
||||
}
|
||||
|
||||
utils.Logger.Errorw("❌ Redis connection failed",
|
||||
"attempt", i,
|
||||
"addr", addr,
|
||||
"error", err,
|
||||
)
|
||||
|
||||
time.Sleep(backoff)
|
||||
backoff *= 2
|
||||
}
|
||||
|
||||
utils.Logger.Fatalw("☢️ CRITICAL: Redis connection failed after retries", "addr", addr)
|
||||
}
|
||||
Reference in New Issue
Block a user