go-mongo/main.go

103 lines
2.4 KiB
Go

package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"time"
"git.farahty.com/nimer/go-mongo/app"
"github.com/fatih/color"
)
func main() {
// Setup cancelable root context
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Panic recovery
defer func() {
if r := recover(); r != nil {
color.Red("🔴 Panic occurred: %v\n", r)
os.Exit(1)
}
}()
color.Yellow("🚀 Starting server ...\n")
// Load and validate config
err := app.LoadConfig()
if err != nil {
log.Fatal("🔴 Config error: ", err)
}
// Connect to Mongo
dbCancel, err := app.Connect()
if err != nil {
log.Fatalf("🔴 MongoDB connection error: %v", err)
}
defer func() {
color.Red("❌ Closing MongoDB connection...\n")
dbCancel()
if err := app.Mongo.Disconnect(ctx); err != nil {
log.Fatal("🔴 MongoDB disconnection error: ", err)
}
}()
color.Green("✅ Connected to MongoDB successfully\n")
// Load authorization policies using root context
if err := app.LoadAuthorizer(ctx); err != nil {
log.Fatal("🔴 Authorizer error: ", err)
}
color.Green("✅ Authorization policies loaded successfully\n")
// Redis
if err := app.InitRedis(ctx); err != nil {
log.Fatal("🔴 Redis connection error: ", err)
}
defer func() {
color.Red("❌ Closing Redis connection...\n")
_ = app.RedisClient.Close()
}()
color.Green("✅ Connected to Redis cache successfully\n")
// Create GraphQL server
graphqlServer := createGraphqlServer()
// Start HTTP server
server := &http.Server{
Addr: ":" + app.Config.Port,
Handler: createRouter(graphqlServer),
ReadTimeout: 30 * time.Second,
WriteTimeout: 30 * time.Second,
IdleTimeout: 30 * time.Second,
}
go func() {
color.Green("🌐 Server listening at http://localhost:%s\n", app.Config.Port)
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("🔴 Server failed: %v", err)
}
}()
// Graceful shutdown
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt)
<-quit
color.Yellow("🟡 Shutdown signal received, initiating cleanup...")
// Cancel root context and wait for graceful shutdown
shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 15*time.Second)
defer shutdownCancel()
if err := server.Shutdown(shutdownCtx); err != nil {
log.Fatalf("🔴 Server forced to shutdown: %v", err)
}
color.Green("✅ Server shutdown completed gracefully")
}