refactor(app): 使用配置化关闭超时替代硬编码
移除硬编码的 shutdownTimeout 变量,改用配置中的 Shutdown.GracefulTimeout 和 Shutdown.FastTimeout: - handleSignal 从配置读取超时值 - gracefulUpgrade 使用配置的优雅停止超时 - 添加防御性 nil-check 确保配置和服务器实例存在 - Windows 版本同步更新 Windows 和 Unix 平台行为一致化。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0152dd1d35
commit
5bb67f13a0
@ -53,12 +53,6 @@ var (
|
||||
BuildPlatform = "unknown"
|
||||
)
|
||||
|
||||
// 应用状态。
|
||||
var (
|
||||
// shutdownTimeout 优雅停止超时时间
|
||||
shutdownTimeout = 30 * time.Second
|
||||
)
|
||||
|
||||
// App 应用程序结构。
|
||||
//
|
||||
// 管理服务器的完整生命周期,包括 HTTP 服务器、HTTP/3 服务器、Stream 服务器
|
||||
@ -349,22 +343,42 @@ func (a *App) setupSignalHandlers(sigChan chan<- os.Signal) {
|
||||
|
||||
// handleSignal 处理信号,返回 false 表示退出。
|
||||
func (a *App) handleSignal(sig os.Signal) bool {
|
||||
// 防御性 nil-check:确保 a.cfg 不为 nil
|
||||
if a.cfg == nil {
|
||||
a.logger.Error().Msg("信号处理失败: 配置为 nil,使用默认超时")
|
||||
// 使用默认超时继续处理信号
|
||||
a.cfg = &config.Config{
|
||||
Shutdown: config.ShutdownConfig{
|
||||
GracefulTimeout: 30 * time.Second,
|
||||
FastTimeout: 5 * time.Second,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
switch sig {
|
||||
case syscall.SIGQUIT:
|
||||
// 优雅停止:等待请求完成
|
||||
a.logger.LogSignal("SIGQUIT", fmt.Sprintf("优雅停止(等待 %v)", shutdownTimeout))
|
||||
timeout := a.cfg.Shutdown.GracefulTimeout
|
||||
if timeout <= 0 {
|
||||
timeout = 30 * time.Second // 默认值
|
||||
}
|
||||
a.logger.LogSignal("SIGQUIT", fmt.Sprintf("优雅停止(等待 %v)", timeout))
|
||||
a.shutdownHTTP2()
|
||||
a.shutdownHTTP3()
|
||||
_ = a.srv.GracefulStop(shutdownTimeout) //nolint:errcheck
|
||||
_ = a.srv.GracefulStop(timeout) //nolint:errcheck
|
||||
return false
|
||||
|
||||
case syscall.SIGTERM, syscall.SIGINT:
|
||||
// 快速停止
|
||||
timeout := a.cfg.Shutdown.FastTimeout
|
||||
if timeout <= 0 {
|
||||
timeout = 5 * time.Second // 默认值
|
||||
}
|
||||
sigTyped := sig.(syscall.Signal) //nolint:errcheck // 类型断言
|
||||
a.logger.LogSignal(sigName(sigTyped), "停止服务器")
|
||||
a.shutdownHTTP2()
|
||||
a.shutdownHTTP3()
|
||||
_ = a.srv.Stop() //nolint:errcheck
|
||||
_ = a.srv.StopWithTimeout(timeout) //nolint:errcheck // 使用新方法
|
||||
return false
|
||||
|
||||
case syscall.SIGHUP:
|
||||
@ -442,6 +456,12 @@ func (a *App) gracefulUpgrade() {
|
||||
return
|
||||
}
|
||||
|
||||
// 防御性 nil-check:确保 srv 不为 nil
|
||||
if a.srv == nil {
|
||||
a.logger.Error().Msg("热升级失败: 服务器实例为 nil")
|
||||
return
|
||||
}
|
||||
|
||||
// 尝试从服务器获取监听器
|
||||
listeners := a.srv.GetListeners()
|
||||
if len(listeners) == 0 {
|
||||
@ -461,10 +481,14 @@ func (a *App) gracefulUpgrade() {
|
||||
|
||||
a.logger.LogStartup("热升级已启动,新进程正在接管", nil)
|
||||
|
||||
// 当前进程优雅停止
|
||||
// 当前进程优雅停止 - 使用配置的超时
|
||||
timeout := a.cfg.Shutdown.GracefulTimeout
|
||||
if timeout <= 0 {
|
||||
timeout = 30 * time.Second
|
||||
}
|
||||
a.shutdownHTTP2()
|
||||
a.shutdownHTTP3()
|
||||
_ = a.srv.GracefulStop(shutdownTimeout) //nolint:errcheck
|
||||
_ = a.srv.GracefulStop(timeout) //nolint:errcheck
|
||||
}
|
||||
|
||||
// sigName 返回信号名称(用于日志输出)。
|
||||
|
||||
@ -36,8 +36,6 @@ var (
|
||||
BuildPlatform = "unknown"
|
||||
)
|
||||
|
||||
var shutdownTimeout = 30 * time.Second
|
||||
|
||||
// App 应用程序结构(Windows 版本)。
|
||||
type App struct {
|
||||
cfgPath string
|
||||
@ -282,10 +280,15 @@ func (a *App) setupSignalHandlers(sigChan chan<- os.Signal) {
|
||||
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)), "停止服务器")
|
||||
a.shutdownHTTP2()
|
||||
a.shutdownHTTP3()
|
||||
_ = a.srv.Stop()
|
||||
_ = a.srv.StopWithTimeout(timeout) //nolint:errcheck // 使用新方法
|
||||
return false
|
||||
default:
|
||||
a.logger.Info().Str("signal", sig.String()).Msg("收到信号(Windows 忽略)")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user