You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

74 lines
1.5 KiB

package exit
import (
"log"
"os"
"os/signal"
"sig-pub/pkg/zlog"
"sync"
"sync/atomic"
"syscall"
"time"
)
var (
AwaitSeconds = 3
shutdownHooks [3][]func() // front,middle,back hooks
lock = &sync.Mutex{}
sigChan = make(chan os.Signal, 1)
)
func AddHook(hook func(), options ...Option) {
opts := defaultOptions
for _, opt := range options {
opt(&opts)
}
lock.Lock()
defer lock.Unlock()
shutdownHooks[opts.Order] = append(shutdownHooks[opts.Order], hook)
}
func Await() {
// 监听两个信号: TERM信号(kill + 进程号)触发, 中断信号(ctrl + c)触发
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
s := <-sigChan
// 监听到关闭信号
zlog.Info("catch exit signal: ", s)
awaitSeconds := AwaitSeconds
var success, fail int32
for i, hooks := range shutdownHooks {
for _, hook := range hooks {
func() {
defer func() {
if err := recover(); err != nil {
log.Println("exec shutdown hook panic: ", err)
atomic.AddInt32(&fail, 1)
return
}
atomic.AddInt32(&success, 1)
}()
hook()
}()
}
// 间隔1s再执行
if i < 2 && len(hooks) > 0 {
time.Sleep(time.Second)
awaitSeconds -= 1
}
}
if awaitSeconds < 1 {
awaitSeconds = 1
}
zlog.Infof("execute %d shutdown hook %d ok, %d failed, exit in %d seconds...\n", success+fail, success, fail, awaitSeconds)
time.Sleep(time.Second * time.Duration(awaitSeconds))
}
//func Shutdown() {
// sigChan <- syscall.SIGQUIT
//}