//go:build windows // Windows lacks POSIX signals (SIGUSR1, SIGUSR2, SIGHUP, SIGQUIT); // this file provides stub implementations for those Unix-specific signals. // Package app 提供 Lolly 应用程序的生命周期管理和命令行入口。 // // 包含 Windows 平台特定的应用逻辑。 // // 作者:xfy package app import ( "fmt" "os" "os/signal" "syscall" "time" "rua.plus/lolly/internal/server" ) // Run starts the application: loads config, creates servers, and handles signals (Windows version). func (a *App) Run() int { if err := a.loadAndValidateConfig(); err != nil { return 1 } a.initVariables() a.logServerAddresses() a.initResolver() a.initServer() a.initStreamServers() a.initHTTP3() a.initHTTP2() a.upgradeMgr = server.NewUpgradeManager(a.srv) if a.pidFile != "" { a.upgradeMgr.SetPidFile(a.pidFile) _ = a.upgradeMgr.WritePid() } sigChan := make(chan os.Signal, 1) a.setupSignalHandlers(sigChan) errChan := make(chan error, 1) go func() { a.logger.LogStartup("Starting HTTP server", nil) if err := a.srv.Start(); err != nil { errChan <- err } }() sigintCount := 0 for { select { case err := <-errChan: a.logger.Error().Err(err).Msg("Server failed to start") return 1 case sig := <-sigChan: if sig == syscall.SIGINT { sigintCount++ if sigintCount >= 3 { a.logger.LogShutdown("Received 3 SIGINT, forcing exit") return 1 } } if !a.handleSignal(sig) { a.logger.LogShutdown("Server stopped") return 0 } } } } func (a *App) setupSignalHandlers(sigChan chan<- os.Signal) { signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT, ) } // handleSignal returns false to indicate the app should exit (Windows version). func (a *App) handleSignal(sig os.Signal) bool { switch sig { case syscall.SIGTERM, syscall.SIGINT: timeout := a.cfg.Shutdown.FastTimeout if timeout <= 0 { timeout = 5 * time.Second } a.logger.LogSignal(sigName(sig.(syscall.Signal)), "Stopping server") a.shutdownHTTP2() a.shutdownHTTP3() _ = a.srv.StopWithTimeout(timeout) return false default: a.logger.Info().Str("signal", sig.String()).Msg("Received signal (ignored on Windows)") return true } } func (a *App) reloadConfig() { // Windows stub - functionality limited } func (a *App) gracefulUpgrade() { a.logger.Info().Msg("Graceful upgrade is not supported on Windows") } func sigName(sig syscall.Signal) string { switch sig { case syscall.SIGTERM: return "SIGTERM" case syscall.SIGINT: return "SIGINT" default: return fmt.Sprintf("Signal(%d)", sig) } }