package main import ( "context" "errors" "net/http" "os" "os/signal" "syscall" "time" "github.com/gin-gonic/gin" "github.com/luxsin/app-api/internal/config" "github.com/luxsin/app-api/internal/database" "github.com/luxsin/app-api/internal/cache" "github.com/luxsin/app-api/internal/router" "github.com/luxsin/app-api/internal/search" "github.com/luxsin/app-api/pkg/logger" "go.uber.org/zap" ) func main() { cfg, err := config.Load() if err != nil { panic(err) } if cfg.Env == "production" { gin.SetMode(gin.ReleaseMode) } log, err := logger.New(cfg.Env) if err != nil { panic(err) } defer log.Sync() //nolint:errcheck db, err := database.Open(cfg.Database) if err != nil { log.Fatal("database connect failed", zap.Error(err)) } defer db.Close() log.Info("database connected", zap.String("host", cfg.Database.Host), zap.Int("port", cfg.Database.Port), zap.String("database", cfg.Database.Name), ) searchClient := search.NewClient(cfg.Meilisearch) log.Info("meilisearch configured", zap.String("host", cfg.Meilisearch.Host), zap.String("index", cfg.Meilisearch.Index), ) redisClient := cache.NewClient(cfg.Redis) defer redisClient.Close() log.Info("redis connected", zap.String("host", cfg.Redis.Host), zap.Int("port", cfg.Redis.Port), zap.Int("db", cfg.Redis.Database), ) engine := router.New(log, db, searchClient, redisClient) srv := &http.Server{ Addr: cfg.Addr(), Handler: engine, ReadTimeout: 10 * time.Second, WriteTimeout: 30 * time.Second, IdleTimeout: 60 * time.Second, } go func() { log.Info("server starting", zap.String("addr", cfg.Addr()), zap.String("env", cfg.Env)) if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { log.Fatal("server failed", zap.Error(err)) } }() quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit log.Info("server shutting down") ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := srv.Shutdown(ctx); err != nil { log.Fatal("server shutdown failed", zap.Error(err)) } log.Info("server stopped") }