diff --git a/app/app_test.go b/app/app_test.go new file mode 100644 index 0000000..37fe98f --- /dev/null +++ b/app/app_test.go @@ -0,0 +1,80 @@ +package app + + +import ( + "testing" + "sync" + "fmt" + "time" +) + +func TestAppDefer(t *testing.T) { + + AppDefer(func() {}) + AppDefer(func() {}, func() {}) + + if len(exitWaitHandler.deferFuns) != 3{ + t.Error("AppDefer func have an error #1") + } + + wg := sync.WaitGroup{} + + wg.Add(2) + go func() { + defer wg.Done() + AppDefer(func() {}) + }() + go func() { + defer wg.Done() + AppDefer(func() {}, func() {}) + }() + wg.Wait() + + if len(exitWaitHandler.deferFuns) != 6{ + t.Error("AppDefer func have an error #2") + } + +} + +func TestListenStop(t *testing.T) { + appSig1:= make(chan StopSignal) + ListenStop(appSig1) + + appSig2:= make(chan StopSignal, 1) + ListenStop(appSig2) + + appSig3:= make(chan StopSignal, 2) + ListenStop(appSig3) + + if len(exitWaitHandler.stopSignList) != 3{ + t.Error("TestListenStop have an error #1") + } + sendAppStop() + + go func() { + select{ + case <-appSig1: + fmt.Println("app stop appSig1") + + } + }() + + + go func() { + select{ + case <-appSig2: + fmt.Println("app stop appSig2") + + } + }() + + go func() { + select{ + case <-appSig3: + fmt.Println("app stop appSig3") + + } + }() + + time.Sleep(time.Second) +} \ No newline at end of file diff --git a/app/shutdown.go b/app/shutdown.go index b2a6b52..226f695 100644 --- a/app/shutdown.go +++ b/app/shutdown.go @@ -10,12 +10,16 @@ import ( "sync" "time" "gitee.com/zhucheer/orange/cfg" + "gitee.com/zhucheer/orange/logger" ) +type StopSignal int32 + type exitWait struct { mutex sync.Mutex wg *sync.WaitGroup deferFuns []func() + stopSignList []chan StopSignal } var exitWaitHandler *exitWait @@ -37,6 +41,8 @@ func ExitWaitFunDo(doFun func()){ // AppDefer 应用退出后置操作 func AppDefer(deferFun ...func()){ + exitWaitHandler.mutex.Lock() + defer exitWaitHandler.mutex.Unlock() for _,funcItem:=range deferFun{ if funcItem != nil{ exitWaitHandler.deferFuns=append(exitWaitHandler.deferFuns, funcItem) @@ -44,6 +50,14 @@ func AppDefer(deferFun ...func()){ } } +// ListenStop 订阅app退出信号 +func ListenStop(stopSig chan StopSignal){ + exitWaitHandler.mutex.Lock() + defer exitWaitHandler.mutex.Unlock() + + exitWaitHandler.stopSignList = append(exitWaitHandler.stopSignList, stopSig) +} + // listenShutDownSign 监听推出信号 @@ -59,6 +73,8 @@ func listenShutDownSign(ctx context.Context, httpSrv *http.Server){ select { case <-appsign: fmt.Println("[ORANGE] \033[0;33m app shutdown sign \033[0m ") + // 发送应用退出信号 + sendAppStop() // 关闭http服务 httpSrv.Shutdown(ctx) @@ -68,6 +84,16 @@ func listenShutDownSign(ctx context.Context, httpSrv *http.Server){ } } +// sendAppStop 发送应用退出信号 +func sendAppStop(){ + + for _,stopSigItem:=range exitWaitHandler.stopSignList{ + go func(sig chan StopSignal) { + sig<-StopSignal(1) + }(stopSigItem) + } +} + // appDefer 退出后处理 func appDeferDo(ctx context.Context){ go func() { @@ -79,12 +105,12 @@ func appDeferDo(ctx context.Context){ maxTimeoutContext,_:= context.WithTimeout(ctx, time.Duration(maxTimeout)*time.Second) select{ case <-maxTimeoutContext.Done(): - fmt.Println(fmt.Sprintf("[ORANGE] \033[0;33m app wait %v timeout shutdown \033[0m ", maxTimeout)) + fmt.Println(fmt.Sprintf("[ORANGE] \033[0;33m app wait %v timeout shutdown \033[0m ", maxTimeout)) + logger.Critical("app server shutdown by timeout") os.Exit(0) } }() - for _,funcItem:=range exitWaitHandler.deferFuns{ exitWaitHandler.wg.Add(1) funcItem() diff --git a/cfg/flag_test.go b/cfg/flag_test.go index 81ba1a0..ed5e2b0 100644 --- a/cfg/flag_test.go +++ b/cfg/flag_test.go @@ -1,11 +1 @@ package cfg - -import "testing" - -func TestRun(t *testing.T) { - - obj := FlagParam{} - - obj.Run() - -} diff --git a/project/config/config.toml b/project/config/config.toml index 17a29e9..0f8a285 100644 --- a/project/config/config.toml +++ b/project/config/config.toml @@ -5,7 +5,7 @@ httpPort = 8088 maxBody = 2096157 csrfVerify = false - maxWaitSecond = 120 + maxWaitSecond = 60 [app.logger] level = "INFO" type = "text" diff --git a/project/http/controller/index.go b/project/http/controller/index.go index 4eba0c7..6a03387 100644 --- a/project/http/controller/index.go +++ b/project/http/controller/index.go @@ -10,14 +10,25 @@ import ( func Welcome(c *app.Context) error { + c.ResponseHeader().Set("Content-Type", "application/text") return c.ToString("orange is a fast api framework") } func AppDefer(c *app.Context)error{ + stopSig := make( chan app.StopSignal, 1) + go app.ListenStop(stopSig) + + go func() { + select { + case <-stopSig: + fmt.Println("stopSign====>") + } + }() + go app.ExitWaitFunDo(func() { - for i:=0;i<50;i++{ + for i:=0;i<10;i++{ fmt.Println("===>", i) time.Sleep(time.Second) }