package app import ( "context" "time" "sub2api-cn-relay-manager/internal/config" ) func Bootstrap(ctx context.Context) (*Server, error) { cfg, err := config.LoadStartupFromEnv() if err != nil { return nil, err } adminToken, err := config.LoadAdminTokenFromEnv() if err != nil { return nil, err } adminSession, err := config.LoadAdminSessionFromEnv() if err != nil { return nil, err } stickyRuntime, err := newStickyStoreRuntime(ctx, cfg.RouteRuntime) if err != nil { return nil, err } startBackgroundSchedulers(ctx, cfg, defaultBackgroundSchedulers()) handler := NewAPIHandlerWithAuth(AdminAuthConfig{ Token: adminToken, Username: adminSession.Username, Password: adminSession.Password, SessionTTL: adminSession.SessionTTL, }, NewActionSetWithStickyRuntime(cfg.Database.SQLiteDSN, stickyRuntime)) return NewServer(cfg.Server.ListenAddr, handler, nil), nil } type backgroundSchedulers struct { runBatchImport func(context.Context, string) runReconcile func(context.Context, string, time.Duration) } func defaultBackgroundSchedulers() backgroundSchedulers { return backgroundSchedulers{ runBatchImport: runBatchImportBackgroundScheduler, runReconcile: runReconcileBackgroundScheduler, } } func startBackgroundSchedulers(ctx context.Context, cfg config.StartupConfig, schedulers backgroundSchedulers) { if schedulers.runBatchImport != nil { schedulers.runBatchImport(ctx, cfg.Database.SQLiteDSN) } if cfg.Reconcile.WorkerEnabled && schedulers.runReconcile != nil { schedulers.runReconcile(ctx, cfg.Database.SQLiteDSN, cfg.Reconcile.PollInterval) } }