| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- //go:build wireinject
- // +build wireinject
- package main
- import (
- "context"
- "log"
- "net/http"
- "sync"
- "time"
- "github.com/Wei-Shaw/sub2api/ent"
- "github.com/Wei-Shaw/sub2api/internal/config"
- "github.com/Wei-Shaw/sub2api/internal/handler"
- "github.com/Wei-Shaw/sub2api/internal/payment"
- "github.com/Wei-Shaw/sub2api/internal/repository"
- "github.com/Wei-Shaw/sub2api/internal/securityaudit"
- "github.com/Wei-Shaw/sub2api/internal/server"
- "github.com/Wei-Shaw/sub2api/internal/server/middleware"
- "github.com/Wei-Shaw/sub2api/internal/service"
- "github.com/google/wire"
- "github.com/redis/go-redis/v9"
- )
- type Application struct {
- Server *http.Server
- PromptAudit *securityaudit.PromptService
- PluginManager *service.PluginManager
- Cleanup func()
- }
- func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
- wire.Build(
- // Infrastructure layer ProviderSets
- config.ProviderSet,
- // Business layer ProviderSets
- repository.ProviderSet,
- service.ProviderSet,
- securityaudit.ProviderSet,
- payment.ProviderSet,
- middleware.ProviderSet,
- handler.ProviderSet,
- // Server layer ProviderSet
- server.ProviderSet,
- // Privacy client factory for OpenAI training opt-out
- providePrivacyClientFactory,
- // BuildInfo provider
- provideServiceBuildInfo,
- providePluginHostInfo,
- // Cleanup function provider
- provideCleanup,
- // Application struct
- wire.Struct(new(Application), "Server", "PromptAudit", "PluginManager", "Cleanup"),
- )
- return nil, nil
- }
- func providePrivacyClientFactory() service.PrivacyClientFactory {
- return repository.CreatePrivacyReqClient
- }
- func provideServiceBuildInfo(buildInfo handler.BuildInfo) service.BuildInfo {
- return service.BuildInfo{
- Version: buildInfo.Version,
- BuildType: buildInfo.BuildType,
- }
- }
- func providePluginHostInfo(buildInfo handler.BuildInfo) service.PluginHostInfo {
- return service.PluginHostInfo{
- Version: buildInfo.Version,
- BuildType: buildInfo.BuildType,
- }
- }
- func provideCleanup(
- entClient *ent.Client,
- rdb *redis.Client,
- opsMetricsCollector *service.OpsMetricsCollector,
- opsAggregation *service.OpsAggregationService,
- opsAlertEvaluator *service.OpsAlertEvaluatorService,
- opsCleanup *service.OpsCleanupService,
- opsScheduledReport *service.OpsScheduledReportService,
- opsSystemLogSink *service.OpsSystemLogSink,
- opsService *service.OpsService,
- opsIngressReject *service.OpsIngressRejectAggregator,
- apiKeyService *service.APIKeyService,
- authCacheInvalidationWorker *service.AuthCacheInvalidationWorker,
- schedulerSnapshot *service.SchedulerSnapshotService,
- tokenRefresh *service.TokenRefreshService,
- accountExpiry *service.AccountExpiryService,
- cnProviderBalanceCheck *service.CNProviderBalanceCheckService,
- codexVersionSync *service.OpenAICodexVersionSyncService,
- proxyExpiry *service.ProxyExpiryService,
- accountHealth *service.AccountHealthService,
- margin *service.MarginService,
- spendGuard *service.SpendGuardService,
- subscriptionExpiry *service.SubscriptionExpiryService,
- usageCleanup *service.UsageCleanupService,
- idempotencyCleanup *service.IdempotencyCleanupService,
- batchImageCleanup *service.BatchImageCleanupService,
- batchImageWorker *service.BatchImageWorkerRuntime,
- pricing *service.PricingService,
- emailQueue *service.EmailQueueService,
- billingCache *service.BillingCacheService,
- usageRecordWorkerPool *service.UsageRecordWorkerPool,
- subscriptionService *service.SubscriptionService,
- oauth *service.OAuthService,
- openaiOAuth *service.OpenAIOAuthService,
- geminiOAuth *service.GeminiOAuthService,
- antigravityOAuth *service.AntigravityOAuthService,
- grokOAuth *service.GrokOAuthService,
- openAIGateway *service.OpenAIGatewayService,
- scheduledTestRunner *service.ScheduledTestRunnerService,
- intelligentTests *service.IntelligentTestService,
- backupSvc *service.BackupService,
- paymentOrderExpiry *service.PaymentOrderExpiryService,
- channelMonitorRunner *service.ChannelMonitorRunner,
- channelMonitorV2Aggregator *service.ChannelMonitorV2Aggregator,
- quotaFlusher *service.UserPlatformQuotaUsageFlusher,
- upstreamBillingProbe *service.UpstreamBillingProbeService,
- ollamaCloudUsage *service.OllamaCloudUsageService,
- auditLog *service.AuditLogService,
- openAIAutoReset *service.OpenAIQuotaAutoResetService,
- promptAudit *securityaudit.PromptService,
- pluginManager *service.PluginManager,
- ) func() {
- return func() {
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
- defer cancel()
- type cleanupStep struct {
- name string
- fn func() error
- }
- // 应用层清理步骤可并行执行,基础设施资源(Redis/Ent)最后按顺序关闭。
- parallelSteps := []cleanupStep{
- {"IntelligentTests", func() error {
- if intelligentTests != nil {
- intelligentTests.Stop()
- }
- return nil
- }},
- {"PluginManager", func() error {
- if pluginManager != nil {
- pluginManager.Stop()
- }
- return nil
- }},
- {"OpenAIQuotaAutoResetService", func() error {
- if openAIAutoReset != nil {
- openAIAutoReset.Stop()
- }
- return nil
- }},
- {"OpsIngressRejectAggregator", func() error {
- if opsIngressReject != nil {
- opsIngressReject.Stop()
- }
- return nil
- }},
- {"AuthCacheInvalidationWorker", func() error {
- if authCacheInvalidationWorker != nil {
- authCacheInvalidationWorker.Stop()
- }
- return nil
- }},
- {"AuthCacheInvalidationSubscriber", func() error {
- if apiKeyService != nil {
- apiKeyService.StopAuthCacheInvalidationSubscriber()
- }
- return nil
- }},
- {"OpsRuntimeSettingsRefresh", func() error {
- if opsService != nil {
- opsService.StopRuntimeSettingsRefresh()
- }
- return nil
- }},
- {"PromptAuditService", func() error {
- if promptAudit != nil {
- return promptAudit.Shutdown(ctx)
- }
- return nil
- }},
- {"OpsScheduledReportService", func() error {
- if opsScheduledReport != nil {
- opsScheduledReport.Stop()
- }
- return nil
- }},
- {"OpsCleanupService", func() error {
- if opsCleanup != nil {
- opsCleanup.Stop()
- }
- return nil
- }},
- {"OpsSystemLogSink", func() error {
- if opsSystemLogSink != nil {
- opsSystemLogSink.Stop()
- }
- return nil
- }},
- {"AuditLogService", func() error {
- if auditLog != nil {
- auditLog.Stop()
- }
- return nil
- }},
- {"OpsAlertEvaluatorService", func() error {
- if opsAlertEvaluator != nil {
- opsAlertEvaluator.Stop()
- }
- return nil
- }},
- {"OpsAggregationService", func() error {
- if opsAggregation != nil {
- opsAggregation.Stop()
- }
- return nil
- }},
- {"OpsMetricsCollector", func() error {
- if opsMetricsCollector != nil {
- opsMetricsCollector.Stop()
- }
- return nil
- }},
- {"SchedulerSnapshotService", func() error {
- if schedulerSnapshot != nil {
- schedulerSnapshot.Stop()
- }
- return nil
- }},
- {"UsageCleanupService", func() error {
- if usageCleanup != nil {
- usageCleanup.Stop()
- }
- return nil
- }},
- {"IdempotencyCleanupService", func() error {
- if idempotencyCleanup != nil {
- idempotencyCleanup.Stop()
- }
- return nil
- }},
- {"BatchImageCleanupService", func() error {
- if batchImageCleanup != nil {
- batchImageCleanup.Stop()
- }
- return nil
- }},
- {"BatchImageWorkerRuntime", func() error {
- if batchImageWorker != nil {
- batchImageWorker.Stop()
- }
- return nil
- }},
- {"TokenRefreshService", func() error {
- tokenRefresh.Stop()
- return nil
- }},
- {"AccountExpiryService", func() error {
- accountExpiry.Stop()
- return nil
- }},
- {"CNProviderBalanceCheckService", func() error {
- if cnProviderBalanceCheck != nil {
- cnProviderBalanceCheck.Stop()
- }
- return nil
- }},
- {"OpenAICodexVersionSyncService", func() error {
- codexVersionSync.Stop()
- return nil
- }},
- {"ProxyExpiryService", func() error {
- proxyExpiry.Stop()
- return nil
- }},
- {"AccountHealthService", func() error {
- accountHealth.Stop()
- return nil
- }},
- {"MarginService", func() error {
- margin.Stop()
- return nil
- }},
- {"SpendGuardService", func() error {
- spendGuard.Stop()
- return nil
- }},
- {"SubscriptionExpiryService", func() error {
- subscriptionExpiry.Stop()
- return nil
- }},
- {"SubscriptionService", func() error {
- if subscriptionService != nil {
- subscriptionService.Stop()
- }
- return nil
- }},
- {"PricingService", func() error {
- pricing.Stop()
- return nil
- }},
- {"EmailQueueService", func() error {
- emailQueue.Stop()
- return nil
- }},
- {"BillingCacheService", func() error {
- billingCache.Stop()
- return nil
- }},
- {"UsageRecordWorkerPool", func() error {
- if usageRecordWorkerPool != nil {
- usageRecordWorkerPool.Stop()
- }
- return nil
- }},
- {"OAuthService", func() error {
- oauth.Stop()
- return nil
- }},
- {"OpenAIOAuthService", func() error {
- openaiOAuth.Stop()
- return nil
- }},
- {"GeminiOAuthService", func() error {
- geminiOAuth.Stop()
- return nil
- }},
- {"AntigravityOAuthService", func() error {
- antigravityOAuth.Stop()
- return nil
- }},
- {"GrokOAuthService", func() error {
- if grokOAuth != nil {
- grokOAuth.Stop()
- }
- return nil
- }},
- {"OpenAIWSPool", func() error {
- if openAIGateway != nil {
- openAIGateway.CloseOpenAIWSPool()
- }
- return nil
- }},
- {"ScheduledTestRunnerService", func() error {
- if scheduledTestRunner != nil {
- scheduledTestRunner.Stop()
- }
- return nil
- }},
- {"BackupService", func() error {
- if backupSvc != nil {
- backupSvc.Stop()
- }
- return nil
- }},
- {"PaymentOrderExpiryService", func() error {
- if paymentOrderExpiry != nil {
- paymentOrderExpiry.Stop()
- }
- return nil
- }},
- {"ChannelMonitorV2Aggregator", func() error {
- if channelMonitorV2Aggregator != nil {
- channelMonitorV2Aggregator.Stop()
- }
- return nil
- }},
- {"ChannelMonitorRunner", func() error {
- if channelMonitorRunner != nil {
- channelMonitorRunner.Stop()
- }
- return nil
- }},
- {"UserPlatformQuotaUsageFlusher", func() error {
- if quotaFlusher != nil {
- quotaFlusher.Stop()
- }
- return nil
- }},
- {"UpstreamBillingProbeService", func() error {
- if upstreamBillingProbe != nil {
- upstreamBillingProbe.Stop()
- }
- return nil
- }},
- {"OllamaCloudUsageService", func() error {
- if ollamaCloudUsage != nil {
- ollamaCloudUsage.Stop()
- }
- return nil
- }},
- }
- infraSteps := []cleanupStep{
- {"Redis", func() error {
- if rdb == nil {
- return nil
- }
- return rdb.Close()
- }},
- {"Ent", func() error {
- if entClient == nil {
- return nil
- }
- return entClient.Close()
- }},
- }
- runParallel := func(steps []cleanupStep) {
- var wg sync.WaitGroup
- for i := range steps {
- step := steps[i]
- wg.Add(1)
- go func() {
- defer wg.Done()
- if err := step.fn(); err != nil {
- log.Printf("[Cleanup] %s failed: %v", step.name, err)
- return
- }
- log.Printf("[Cleanup] %s succeeded", step.name)
- }()
- }
- wg.Wait()
- }
- runSequential := func(steps []cleanupStep) {
- for i := range steps {
- step := steps[i]
- if err := step.fn(); err != nil {
- log.Printf("[Cleanup] %s failed: %v", step.name, err)
- continue
- }
- log.Printf("[Cleanup] %s succeeded", step.name)
- }
- }
- runParallel(parallelSteps)
- runSequential(infraSteps)
- // Check if context timed out
- select {
- case <-ctx.Done():
- log.Printf("[Cleanup] Warning: cleanup timed out after 10 seconds")
- default:
- log.Printf("[Cleanup] All cleanup steps completed")
- }
- }
- }
|