lolly/internal/app/app_windows.go
xfy911 57d4d3ba3c docs(app): add package comments for app module
- Add package documentation for app, app_common, import, app_windows, and testutil files
- Include author attribution (xfy)
2026-06-03 15:28:53 +08:00

120 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//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)
}
}