package main import ( "chatapp3-golang/internal/bootstrap" "chatapp3-golang/internal/router" "chatapp3-golang/internal/service/baishun" "chatapp3-golang/internal/service/invite" "chatapp3-golang/internal/service/luckygift" "chatapp3-golang/internal/service/registerreward" "chatapp3-golang/internal/service/signinreward" "chatapp3-golang/internal/service/weekstar" "context" "errors" "log" "net/http" "os/signal" "syscall" "time" _ "time/tzdata" ) func main() { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() app, err := bootstrap.New(ctx) if err != nil { log.Fatalf("bootstrap api failed: %v", err) } inviteService := invite.NewInviteService(app.Config, app.Repository.DB, app.Repository.Redis, &app.Gateways) baishunService := baishun.NewBaishunService(app.Config, app.Repository.DB, app.Repository.Redis, &app.Gateways) luckyGiftService := luckygift.NewLuckyGiftService(app.Config, app.Repository.DB, app.Repository.Redis, app.Gateways.Wallet) registerRewardService := registerreward.NewRegisterRewardService(app.Config, app.Repository.DB, app.Repository.Redis, &app.Gateways) signInRewardService := signinreward.NewSignInRewardService(app.Config, app.Repository.DB, app.Repository.Redis, &app.Gateways) weekStarService := weekstar.NewWeekStarService(app.Config, app.Repository.DB, app.Repository.Redis, &app.Gateways) engine := router.NewRouter(app.Config, app.Repository, &app.Gateways, router.Services{ Invite: inviteService, Baishun: baishunService, LuckyGift: luckyGiftService, RegisterReward: registerRewardService, SignInReward: signInRewardService, WeekStar: weekStarService, }) server := &http.Server{ Addr: app.Config.HTTP.ListenAddr, Handler: engine, ReadHeaderTimeout: 10 * time.Second, } serverErrors := make(chan error, 1) go func() { log.Printf("chatapp3-golang api listening on %s", app.Config.HTTP.ListenAddr) if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { serverErrors <- err return } serverErrors <- nil }() shutdownSignal, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer stop() select { case err := <-serverErrors: if err != nil { log.Fatalf("run server failed: %v", err) } return case <-shutdownSignal.Done(): log.Printf("shutdown signal received, draining http traffic") } shutdownCtx, cancelShutdown := context.WithTimeout(context.Background(), app.Config.HTTP.ShutdownTimeout) defer cancelShutdown() if err := server.Shutdown(shutdownCtx); err != nil { log.Printf("graceful shutdown failed: %v", err) if closeErr := server.Close(); closeErr != nil { log.Printf("force close failed: %v", closeErr) } } if err := <-serverErrors; err != nil { log.Fatalf("server exited with error during shutdown: %v", err) } }