Browse Source

重构,支持在保存配置的时候重启 http 服务器

Signed-off-by: allan716 <[email protected]>
allan716 3 years ago
parent
commit
5f7ad78d00

+ 7 - 4
cmd/chinesesubfinder/main.go

@@ -156,10 +156,13 @@ func main() {
 	nowPort := my_util.ReadCustomPortFile(loggerBase)
 	loggerBase.Infoln(fmt.Sprintf("WebUI will listen at 0.0.0.0:%d", nowPort))
 	// 支持在外部配置特殊的端口号,以防止本地本占用了无法使用
-	bend := backend.NewBackEnd(loggerBase, settings.GetSettings(), cronHelper, nowPort)
-	bend.Start()
-	//// 阻塞
-	//select {}
+	restartSignal := make(chan interface{}, 1)
+	defer close(restartSignal)
+	bend := backend.NewBackEnd(loggerBase, settings.GetSettings(), cronHelper, nowPort, restartSignal)
+	go bend.Restart()
+	restartSignal <- 1
+	// 阻塞
+	select {}
 }
 
 /*

+ 54 - 41
internal/backend/backend.go

@@ -20,26 +20,27 @@ import (
 )
 
 type BackEnd struct {
-	logger     *logrus.Logger
-	settings   *settings.Settings
-	cronHelper *cron_helper.CronHelper
-	httpPort   int
-	running    bool
-	srv        *http.Server
-	locker     sync.Mutex
+	logger        *logrus.Logger
+	settings      *settings.Settings
+	cronHelper    *cron_helper.CronHelper
+	httpPort      int
+	running       bool
+	srv           *http.Server
+	locker        sync.Mutex
+	restartSignal chan interface{}
 }
 
-func NewBackEnd(logger *logrus.Logger, settings *settings.Settings, cronHelper *cron_helper.CronHelper, httpPort int) *BackEnd {
-	return &BackEnd{logger: logger, settings: settings, cronHelper: cronHelper, httpPort: httpPort}
+func NewBackEnd(logger *logrus.Logger, settings *settings.Settings, cronHelper *cron_helper.CronHelper, httpPort int, restartSignal chan interface{}) *BackEnd {
+	return &BackEnd{logger: logger, settings: settings, cronHelper: cronHelper, httpPort: httpPort, restartSignal: restartSignal}
 }
 
-func (b *BackEnd) Start() {
+func (b *BackEnd) start() {
 
 	defer b.locker.Unlock()
 	b.locker.Lock()
 
 	if b.running == true {
-		b.logger.Warningln("Http Server is already running")
+		b.logger.Debugln("Http Server is already running")
 		return
 	}
 	b.running = true
@@ -50,10 +51,7 @@ func (b *BackEnd) Start() {
 	engine := gin.Default()
 	// 默认所有都通过
 	engine.Use(cors.Default())
-	v1Router := InitRouter(b.logger, b.settings, engine, b.cronHelper)
-	defer func() {
-		v1Router.Close()
-	}()
+	v1Router := InitRouter(b.logger, b.settings, engine, b.cronHelper, b.restartSignal)
 
 	engine.GET("/", func(c *gin.Context) {
 		c.Header("content-type", "text/html;charset=utf-8")
@@ -74,35 +72,50 @@ func (b *BackEnd) Start() {
 		Addr:    fmt.Sprintf(":%d", b.httpPort),
 		Handler: engine,
 	}
-	//go func() {
-	b.logger.Infoln("Try Start Http Server At Port", b.httpPort)
-	if err := b.srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
-		b.logger.Errorln("Start Server Error:", err)
-	}
-	//}()
-}
-
-func (b *BackEnd) Stop() {
-	defer func() {
-		b.locker.Unlock()
+	go func() {
+		b.logger.Infoln("Try Start Http Server At Port", b.httpPort)
+		if err := b.srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+			b.logger.Errorln("Start Server Error:", err)
+		}
+		defer func() {
+			v1Router.Close()
+		}()
 	}()
-	b.locker.Lock()
+}
 
-	if b.running == false {
-		b.logger.Warningln("Http Server is not running")
-		return
+func (b *BackEnd) Restart() {
+
+	stopFunc := func() {
+
+		b.locker.Lock()
+		defer func() {
+			b.locker.Unlock()
+		}()
+		if b.running == false {
+			b.logger.Debugln("Http Server is not running")
+			return
+		}
+		b.running = false
+
+		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+		defer cancel()
+		if err := b.srv.Shutdown(ctx); err != nil {
+			b.logger.Errorln("Http Server Shutdown:", err)
+		}
+		select {
+		case <-ctx.Done():
+			b.logger.Warningln("timeout of 5 seconds.")
+		}
+		b.logger.Infoln("Http Server exiting")
 	}
 
-	b.running = false
-
-	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
-	defer cancel()
-	if err := b.srv.Shutdown(ctx); err != nil {
-		b.logger.Errorln("Http Server Shutdown:", err)
-	}
-	select {
-	case <-ctx.Done():
-		b.logger.Warningln("timeout of 5 seconds.")
+	for {
+		select {
+		case <-b.restartSignal:
+			{
+				stopFunc()
+				b. ()
+			}
+		}
 	}
-	b.logger.Infoln("Http Server exiting")
 }

+ 2 - 1
internal/backend/base_router.go

@@ -20,10 +20,11 @@ func InitRouter(
 	settings *settings.Settings, // 设置实例
 	router *gin.Engine,
 	cronHelper *cron_helper.CronHelper,
+	restartSignal chan interface{},
 ) *v1.ControllerBase {
 
 	cbBase := base.NewControllerBase(log)
-	cbV1 := v1.NewControllerBase(log, cronHelper)
+	cbV1 := v1.NewControllerBase(log, cronHelper, restartSignal)
 	// --------------------------------------------------
 	// 静态文件服务器
 	// 添加电影的

+ 3 - 1
internal/backend/controllers/v1/controller_base.go

@@ -21,9 +21,10 @@ type ControllerBase struct {
 	videoScanAndRefreshHelperIsRunning  bool
 	videoScanAndRefreshHelperLocker     lock.Lock
 	videoScanAndRefreshHelperErrMessage string
+	restartSignal                       chan interface{}
 }
 
-func NewControllerBase(log *logrus.Logger, cronHelper *cron_helper.CronHelper) *ControllerBase {
+func NewControllerBase(log *logrus.Logger, cronHelper *cron_helper.CronHelper, restartSignal chan interface{}) *ControllerBase {
 	cb := &ControllerBase{
 		log:        log,
 		cronHelper: cronHelper,
@@ -33,6 +34,7 @@ func NewControllerBase(log *logrus.Logger, cronHelper *cron_helper.CronHelper) *
 			sub_formatter.GetSubFormatter(log, cronHelper.Settings.AdvancedSettings.SubNameFormatter),
 			cronHelper.FileDownloader, nil),
 		videoScanAndRefreshHelperLocker: lock.NewLock(),
+		restartSignal:                   restartSignal,
 	}
 
 	return cb

+ 2 - 0
internal/backend/controllers/v1/settings.go

@@ -61,6 +61,8 @@ func (cb ControllerBase) SettingsHandler(c *gin.Context) {
 			}
 
 			c.JSON(http.StatusOK, backend.ReplyCommon{Message: "Settings Save Success"})
+			// 回复完毕后,发送重启 http server 的信号
+			cb.restartSignal <- 1
 		}
 	default:
 		c.JSON(http.StatusNoContent, backend.ReplyCommon{Message: "Settings Request.Method Error"})