New
This commit is contained in:
142
internal/app/app.go
Normal file
142
internal/app/app.go
Normal file
@@ -0,0 +1,142 @@
|
||||
// Filename: internal/app/app.go
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"gemini-balancer/internal/config"
|
||||
"gemini-balancer/internal/crypto"
|
||||
"gemini-balancer/internal/db/migrations"
|
||||
"gemini-balancer/internal/db/seeder"
|
||||
"gemini-balancer/internal/scheduler"
|
||||
"gemini-balancer/internal/service"
|
||||
"gemini-balancer/internal/settings"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// App
|
||||
type App struct {
|
||||
Config *config.Config
|
||||
Router *gin.Engine
|
||||
DB *gorm.DB
|
||||
Logger *logrus.Logger
|
||||
CryptoService *crypto.Service
|
||||
|
||||
// 拥有独立生命周期的后台服务
|
||||
ResourceService *service.ResourceService
|
||||
APIKeyService *service.APIKeyService
|
||||
DBLogWriter *service.DBLogWriterService
|
||||
AnalyticsService *service.AnalyticsService
|
||||
HealthCheckService *service.HealthCheckService
|
||||
SettingsManager *settings.SettingsManager
|
||||
GroupManager *service.GroupManager
|
||||
TokenManager *service.TokenManager
|
||||
Scheduler *scheduler.Scheduler
|
||||
}
|
||||
|
||||
// NewApp
|
||||
func NewApp(
|
||||
cfg *config.Config,
|
||||
router *gin.Engine,
|
||||
db *gorm.DB,
|
||||
logger *logrus.Logger,
|
||||
cryptoService *crypto.Service,
|
||||
resourceService *service.ResourceService,
|
||||
apiKeyService *service.APIKeyService,
|
||||
dbLogWriter *service.DBLogWriterService,
|
||||
analyticsService *service.AnalyticsService,
|
||||
healthCheckService *service.HealthCheckService,
|
||||
settingsManager *settings.SettingsManager,
|
||||
groupManager *service.GroupManager,
|
||||
tokenManager *service.TokenManager,
|
||||
scheduler *scheduler.Scheduler,
|
||||
) *App {
|
||||
return &App{
|
||||
Config: cfg,
|
||||
Router: router,
|
||||
DB: db,
|
||||
Logger: logger,
|
||||
CryptoService: cryptoService,
|
||||
ResourceService: resourceService,
|
||||
APIKeyService: apiKeyService,
|
||||
DBLogWriter: dbLogWriter,
|
||||
AnalyticsService: analyticsService,
|
||||
HealthCheckService: healthCheckService,
|
||||
SettingsManager: settingsManager,
|
||||
GroupManager: groupManager,
|
||||
TokenManager: tokenManager,
|
||||
Scheduler: scheduler,
|
||||
}
|
||||
}
|
||||
|
||||
// Run 启动流程现在由App主动编排,而非被动接受
|
||||
func (a *App) Run() error {
|
||||
// --- 阶段一: (数据库设置) ---
|
||||
a.Logger.Info("* [SYSTEM] * Preparing: Database Setup ...")
|
||||
|
||||
// 步骤 1: (运行基础迁移,确保表存在)
|
||||
if err := migrations.RunMigrations(a.DB, a.Logger); err != nil {
|
||||
return fmt.Errorf("initial database migration failed: %w", err)
|
||||
}
|
||||
|
||||
// 步骤 2: (运行所有版本化的数据迁移)
|
||||
if err := migrations.RunVersionedMigrations(a.DB, a.Config, a.Logger); err != nil {
|
||||
return fmt.Errorf("failed to run versioned migrations: %w", err)
|
||||
}
|
||||
|
||||
// 步骤 3: (数据播种)
|
||||
seeder.RunSeeder(a.DB, a.CryptoService, a.Logger)
|
||||
a.Logger.Info("* [SYSTEM] * All Uitls READY. ---")
|
||||
|
||||
// --- 阶段二: (启动后台服务) ---
|
||||
a.Logger.Info("* [SYSTEM] * Starting main: Background Services ")
|
||||
a.APIKeyService.Start()
|
||||
a.DBLogWriter.Start()
|
||||
a.AnalyticsService.Start()
|
||||
a.HealthCheckService.Start()
|
||||
a.Scheduler.Start()
|
||||
a.Logger.Info("* [SYSTEM] * All Background Services are RUNNING. ")
|
||||
|
||||
// --- 阶段三: (优雅关机) ---
|
||||
defer a.Scheduler.Stop()
|
||||
defer a.HealthCheckService.Stop()
|
||||
defer a.AnalyticsService.Stop()
|
||||
defer a.APIKeyService.Stop()
|
||||
defer a.DBLogWriter.Stop()
|
||||
defer a.SettingsManager.Stop()
|
||||
defer a.TokenManager.Stop()
|
||||
|
||||
// --- 阶段四: (HTTP服务器) ---
|
||||
serverAddr := fmt.Sprintf("0.0.0.0:%s", a.Config.Server.Port)
|
||||
srv := &http.Server{
|
||||
Addr: serverAddr,
|
||||
Handler: a.Router,
|
||||
}
|
||||
go func() {
|
||||
a.Logger.Infof("* [SYSTEM] * HTTP Server Now Listening on %s ", serverAddr)
|
||||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
a.Logger.Fatalf("HTTP server listen error: %s\n", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// --- 阶段五: (处理关机信号) ---
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-quit
|
||||
a.Logger.Info("* [SYSTEM] * Shutdown signal received. Executing strategic retreat...")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
if err := srv.Shutdown(ctx); err != nil {
|
||||
a.Logger.Fatal("Server forced to shutdown:", err)
|
||||
}
|
||||
a.Logger.Info("* [SYSTEM] * All units have ceased operations. Mission complete. ")
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user