支持服务优雅关闭,避免重启回复中断和面板缓存数据丢失 (#4258)
* feat: add graceful shutdown with configurable timeout * fix: flush quota dashboard cache on graceful shutdown Persist the in-memory CacheQuotaData aggregation to the quota_data table before process exit, so a restart no longer drops up to one DataExportInterval window of dashboard data (issue #5679).
This commit is contained in:
@@ -2,13 +2,17 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/QuantumNous/new-api/common"
|
||||
@@ -209,10 +213,34 @@ func main() {
|
||||
// Log startup success message
|
||||
common.LogStartupSuccess(startTime, port)
|
||||
|
||||
err = server.Run(":" + port)
|
||||
if err != nil {
|
||||
common.FatalLog("failed to start HTTP server: " + err.Error())
|
||||
srv := &http.Server{
|
||||
Addr: ":" + port,
|
||||
Handler: server,
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
common.FatalLog("failed to start HTTP server: " + err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||
sig := <-quit
|
||||
common.SysLog(fmt.Sprintf("received signal: %v, shutting down...", sig))
|
||||
|
||||
// SSE streams may run for minutes; give them time to finish before forced exit
|
||||
shutdownTimeout := time.Duration(common.GetEnvOrDefault("SHUTDOWN_TIMEOUT_SECONDS", 120)) * time.Second
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
|
||||
defer cancel()
|
||||
if err := srv.Shutdown(ctx); err != nil {
|
||||
common.SysError(fmt.Sprintf("server forced to shutdown: %v", err))
|
||||
}
|
||||
// 内存中的看板数据保存入库,避免重启丢失未落库数据 (issue #5679)
|
||||
if common.DataExportEnabled {
|
||||
model.SaveQuotaDataCache()
|
||||
}
|
||||
common.SysLog("server exited")
|
||||
}
|
||||
|
||||
func InjectUmamiAnalytics() {
|
||||
|
||||
Reference in New Issue
Block a user