应用自定义退出信号

This commit is contained in:
zhucheer 2020-02-02 00:21:11 +08:00
parent 0235c5cabb
commit e2b7c526e1
5 changed files with 121 additions and 14 deletions

80
app/app_test.go Normal file
View File

@ -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)
}

View File

@ -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()

View File

@ -1,11 +1 @@
package cfg
import "testing"
func TestRun(t *testing.T) {
obj := FlagParam{}
obj.Run()
}

View File

@ -5,7 +5,7 @@
httpPort = 8088
maxBody = 2096157
csrfVerify = false
maxWaitSecond = 120
maxWaitSecond = 60
[app.logger]
level = "INFO"
type = "text"

View File

@ -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)
}