From a4831ec6a65825b8d13fdc2e24f3010f03923cc3 Mon Sep 17 00:00:00 2001
From: "CTFang@WireLab" <ctfang.cs12@nycu.edu.tw>
Date: Thu, 9 May 2024 03:58:08 +0000
Subject: [PATCH] perf: update Web App termination procedure

---
 backend/billing/server.go               | 27 ++++++--------
 backend/webui_context/context.go        |  7 ++--
 backend/webui_context/nrf_management.go |  2 +-
 backend/webui_service/webui_init.go     | 47 +++++++++++++++++--------
 4 files changed, 49 insertions(+), 34 deletions(-)

diff --git a/backend/billing/server.go b/backend/billing/server.go
index f2ef046..e2a98c8 100644
--- a/backend/billing/server.go
+++ b/backend/billing/server.go
@@ -6,7 +6,6 @@ import (
 	"os"
 	"strconv"
 	"sync"
-	"time"
 
 	"github.com/fclairamb/ftpserver/config"
 	"github.com/fclairamb/ftpserver/server"
@@ -19,6 +18,7 @@ import (
 type BillingDomain struct {
 	ftpServer *ftpserver.FtpServer
 	driver    *server.Server
+	wg        *sync.WaitGroup
 }
 
 type Access struct {
@@ -39,7 +39,9 @@ func OpenServer(wg *sync.WaitGroup) *BillingDomain {
 	// Arguments vars
 	confFile := "/tmp/webconsole/ftpserver.json"
 
-	b := &BillingDomain{}
+	b := &BillingDomain{
+		wg: wg,
+	}
 	if _, err := os.Stat("/tmp/webconsole"); err != nil {
 		if err := os.Mkdir("/tmp/webconsole", os.ModePerm); err != nil {
 			logger.BillingLog.Error(err)
@@ -105,33 +107,26 @@ func OpenServer(wg *sync.WaitGroup) *BillingDomain {
 	// Setting up the ftpserver logger
 	b.ftpServer.Logger = logger.FtpServerLog
 
-	go b.Serve(wg)
+	go b.Serve()
 	logger.BillingLog.Info("Billing server Start")
 
 	return b
 }
 
-func (b *BillingDomain) Serve(wg *sync.WaitGroup) {
-	defer func() {
-		logger.BillingLog.Error("Billing server stopped")
-		b.Stop()
-		wg.Done()
-	}()
-
+func (b *BillingDomain) Serve() {
 	if err := b.ftpServer.ListenAndServe(); err != nil {
 		logger.BillingLog.Error("Problem listening ", "err", err)
 	}
-
-	// We wait at most 1 minutes for all clients to disconnect
-	if err := b.driver.WaitGracefully(time.Minute); err != nil {
-		logger.BillingLog.Warn("Problem stopping server", "Err", err)
-	}
 }
 
 func (b *BillingDomain) Stop() {
-	b.driver.Stop()
+	logger.BillingLog.Infoln("Stop BillingDomain server")
 
+	b.driver.Stop()
 	if err := b.ftpServer.Stop(); err != nil {
 		logger.BillingLog.Error("Problem stopping server", "Err", err)
 	}
+
+	logger.BillingLog.Infoln("BillingDomain server stopped")
+	b.wg.Done()
 }
diff --git a/backend/webui_context/context.go b/backend/webui_context/context.go
index 3414c33..6f938b3 100644
--- a/backend/webui_context/context.go
+++ b/backend/webui_context/context.go
@@ -10,7 +10,6 @@ import (
 	"github.com/free5gc/openapi/Nnrf_NFManagement"
 	"github.com/free5gc/openapi/models"
 	"github.com/free5gc/openapi/oauth"
-	"github.com/free5gc/webconsole/backend/billing"
 	"github.com/free5gc/webconsole/backend/factory"
 	"github.com/free5gc/webconsole/backend/logger"
 )
@@ -21,7 +20,9 @@ type WEBUIContext struct {
 	NfInstanceID   string
 	NFProfiles     []models.NfProfile
 	NFOamInstances []NfOamInstance
-	BillingServer  *billing.BillingDomain
+
+	// is registered to NRF as AF
+	IsRegistered bool
 
 	NrfUri         string
 	OAuth2Required bool
@@ -40,6 +41,8 @@ func Init() {
 	webuiContext.NfInstanceID = uuid.New().String()
 	webuiContext.NrfUri = factory.WebuiConfig.Configuration.NrfUri
 
+	webuiContext.IsRegistered = false
+
 	ManagementConfig := Nnrf_NFManagement.NewConfiguration()
 	ManagementConfig.SetBasePath(GetSelf().NrfUri)
 	webuiContext.NFManagementClient = Nnrf_NFManagement.NewAPIClient(ManagementConfig)
diff --git a/backend/webui_context/nrf_management.go b/backend/webui_context/nrf_management.go
index c404d97..1e6224f 100644
--- a/backend/webui_context/nrf_management.go
+++ b/backend/webui_context/nrf_management.go
@@ -33,7 +33,7 @@ func SendNFRegistration() error {
 			NFInstanceIDDocumentApi.
 			RegisterNFInstance(context.TODO(), GetSelf().NfInstanceID, profile)
 		if err != nil || res == nil {
-			logger.ConsumerLog.Infof("Webconsole-AF register to NRF Error[%s]", err.Error())
+			logger.ConsumerLog.Warnf("Webconsole-AF register to NRF Error[%s]", err.Error())
 			time.Sleep(2 * time.Second)
 			retryTime += 1
 			if retryTime == 10 {
diff --git a/backend/webui_service/webui_init.go b/backend/webui_service/webui_init.go
index 2b9c901..7f41963 100644
--- a/backend/webui_service/webui_init.go
+++ b/backend/webui_service/webui_init.go
@@ -22,10 +22,17 @@ import (
 type WebuiApp struct {
 	cfg      *factory.Config
 	webuiCtx *webui_context.WEBUIContext
+
+	wg *sync.WaitGroup
+
+	billingServer *billing.BillingDomain
 }
 
 func NewApp(cfg *factory.Config) (*WebuiApp, error) {
-	webui := &WebuiApp{cfg: cfg}
+	webui := &WebuiApp{
+		cfg: cfg,
+		wg:  &sync.WaitGroup{},
+	}
 	webui.SetLogEnable(cfg.GetLogEnable())
 	webui.SetLogLevel(cfg.GetLogLevel())
 	webui.SetReportCaller(cfg.GetLogReportCaller())
@@ -87,6 +94,7 @@ func (a *WebuiApp) Start(tlsKeyLogPath string) {
 
 	logger.InitLog.Infoln("Server started")
 
+	a.wg.Add(1)
 	signalChannel := make(chan os.Signal, 1)
 	signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM)
 	go func() {
@@ -99,7 +107,7 @@ func (a *WebuiApp) Start(tlsKeyLogPath string) {
 
 		<-signalChannel
 		a.Terminate()
-		os.Exit(0)
+		a.wg.Done()
 	}()
 
 	go func() {
@@ -110,6 +118,8 @@ func (a *WebuiApp) Start(tlsKeyLogPath string) {
 				logger.InitLog.Errorln(retry_err)
 				logger.InitLog.Warningln("The registration to NRF failed, resulting in limited functionalities.")
 			}
+		} else {
+			a.webuiCtx.IsRegistered = true
 		}
 	}()
 
@@ -135,12 +145,10 @@ func (a *WebuiApp) Start(tlsKeyLogPath string) {
 	self := webui_context.GetSelf()
 	self.UpdateNfProfiles()
 
-	wg := sync.WaitGroup{}
-
 	if billingServer.Enable {
-		wg.Add(1)
-		self.BillingServer = billing.OpenServer(&wg)
-		if self.BillingServer == nil {
+		a.wg.Add(1)
+		a.billingServer = billing.OpenServer(a.wg)
+		if a.billingServer == nil {
 			logger.InitLog.Errorln("Billing Server open error.")
 		}
 	}
@@ -153,19 +161,28 @@ func (a *WebuiApp) Start(tlsKeyLogPath string) {
 		logger.InitLog.Infoln(router.Run(":5000"))
 	}
 
-	wg.Wait()
+	logger.MainLog.Infoln("wait all routine stopped")
+	a.wg.Wait()
 }
 
 func (a *WebuiApp) Terminate() {
 	logger.InitLog.Infoln("Terminating WebUI-AF...")
 
+	if a.billingServer != nil {
+		a.billingServer.Stop()
+	}
+
 	// Deregister with NRF
-	problemDetails, err := webui_context.SendDeregisterNFInstance()
-	if problemDetails != nil {
-		logger.InitLog.Errorf("Deregister NF instance Failed Problem[%+v]", problemDetails)
-	} else if err != nil {
-		logger.InitLog.Errorf("Deregister NF instance Error[%+v]", err)
-	} else {
-		logger.InitLog.Infof("Deregister from NRF successfully")
+	if a.webuiCtx.IsRegistered {
+		problemDetails, err := webui_context.SendDeregisterNFInstance()
+		if problemDetails != nil {
+			logger.InitLog.Errorf("Deregister NF instance Failed Problem[%+v]", problemDetails)
+		} else if err != nil {
+			logger.InitLog.Errorf("Deregister NF instance Error[%+v]", err)
+		} else {
+			logger.InitLog.Infof("Deregister from NRF successfully")
+		}
 	}
+
+	logger.InitLog.Infoln("WebUI-AF Terminated")
 }
-- 
GitLab