Feat: sys notify add reload task

pull/3/head
zijiren233 2 years ago
parent 2f44e7bdeb
commit f84ee186d1

@ -10,31 +10,45 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/zijiren233/gencontainer/pqueue" "github.com/zijiren233/gencontainer/pqueue"
"github.com/zijiren233/gencontainer/rwmap"
) )
var ( var (
c chan os.Signal c chan os.Signal
notifyTaskLock sync.Mutex once sync.Once
notifyTaskQueue = pqueue.NewMaxPriorityQueue[*SysNotifyTask]() TaskGroup rwmap.RWMap[NotifyType, *taskQueue]
once sync.Once WaitCbk func()
WaitCbk func() )
type NotifyType int
const (
NotifyTypeEXIT NotifyType = iota + 1
NotifyTypeRELOAD
) )
type taskQueue struct {
notifyTaskLock sync.Mutex
notifyTaskQueue *pqueue.PQueue[*SysNotifyTask]
}
type SysNotifyTask struct { type SysNotifyTask struct {
Task func() error Task func() error
Name string NotifyType NotifyType
Name string
} }
func NewSysNotifyTask(name string, task func() error) *SysNotifyTask { func NewSysNotifyTask(name string, NotifyType NotifyType, task func() error) *SysNotifyTask {
return &SysNotifyTask{ return &SysNotifyTask{
Name: name, Name: name,
Task: task, NotifyType: NotifyType,
Task: task,
} }
} }
func InitSysNotify() { func InitSysNotify() {
c = make(chan os.Signal, 1) c = make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP /*1*/, syscall.SIGINT /*2*/, syscall.SIGQUIT /*3*/, syscall.SIGTERM /*15*/) signal.Notify(c, syscall.SIGHUP /*1*/, syscall.SIGINT /*2*/, syscall.SIGQUIT /*3*/, syscall.SIGTERM /*15*/, syscall.SIGUSR1 /*10*/, syscall.SIGUSR2 /*12*/)
WaitCbk = func() { WaitCbk = func() {
once.Do(waitCbk) once.Do(waitCbk)
} }
@ -42,12 +56,32 @@ func InitSysNotify() {
func waitCbk() { func waitCbk() {
log.Info("wait sys notify") log.Info("wait sys notify")
log.Infof("receive sys notify: %v", <-c) for s := range c {
notifyTaskLock.Lock() log.Infof("receive sys notify: %v", s)
defer notifyTaskLock.Unlock() switch s {
log.Infof("task: running...") case syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM:
for notifyTaskQueue.Len() > 0 { tq, ok := TaskGroup.Load(NotifyTypeEXIT)
_, task := notifyTaskQueue.Pop() if ok {
log.Info("task: NotifyTypeEXIT running...")
runTask(tq)
}
return
case syscall.SIGUSR1, syscall.SIGUSR2:
tq, ok := TaskGroup.Load(NotifyTypeRELOAD)
if ok {
log.Info("task: NotifyTypeRELOAD running...")
runTask(tq)
}
}
log.Info("task: all done")
}
}
func runTask(tq *taskQueue) {
tq.notifyTaskLock.Lock()
defer tq.notifyTaskLock.Unlock()
for tq.notifyTaskQueue.Len() > 0 {
_, task := tq.notifyTaskQueue.Pop()
func() { func() {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
@ -61,15 +95,20 @@ func waitCbk() {
log.Infof("task: %s done", task.Name) log.Infof("task: %s done", task.Name)
}() }()
} }
log.Info("task: all done")
} }
func RegisterSysNotifyTask(priority int, task *SysNotifyTask) error { func RegisterSysNotifyTask(priority int, task *SysNotifyTask) error {
if task == nil || task.Task == nil { if task == nil || task.Task == nil {
return errors.New("task is nil") return errors.New("task is nil")
} }
notifyTaskLock.Lock() if task.NotifyType == 0 {
defer notifyTaskLock.Unlock() panic("task notify type is 0")
notifyTaskQueue.Push(priority, task) }
tasks, _ := TaskGroup.LoadOrStore(task.NotifyType, &taskQueue{
notifyTaskQueue: pqueue.NewMinPriorityQueue[*SysNotifyTask](),
})
tasks.notifyTaskLock.Lock()
defer tasks.notifyTaskLock.Unlock()
tasks.notifyTaskQueue.Push(priority, task)
return nil return nil
} }

Loading…
Cancel
Save