88 lines
1.8 KiB
Go
88 lines
1.8 KiB
Go
package l_notify
|
||
|
||
import (
|
||
"fmt"
|
||
"gitea.cdlsxd.cn/self-tools/l_request"
|
||
"github.com/robfig/cron/v3"
|
||
)
|
||
|
||
type Notify struct {
|
||
Request *l_request.Request
|
||
DoFuc func() (l_request.Response, error) //测试用
|
||
DelayList []int32 //[30,60,120...]:从前往后分别延迟30秒,60秒,120秒...推送,[60]:每隔60秒推送一次
|
||
ResultHandle func(l_request.Response, error) (stop bool) //推送结果处理函数,stop为true时表示停止推送
|
||
cron *cron.Cron
|
||
stop chan struct{}
|
||
currenEntry cron.EntryID
|
||
isLoop bool
|
||
i int8
|
||
}
|
||
|
||
func (n *Notify) Notify() error {
|
||
//必要参数检测
|
||
err := n.check()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
if len(n.DelayList) == 1 {
|
||
//如果只有一次,则默认循环推送
|
||
n.isLoop = true
|
||
}
|
||
|
||
n.stop = make(chan struct{})
|
||
//启动定时器
|
||
n.cron = cron.New()
|
||
n.next()
|
||
n.cron.Start()
|
||
|
||
return nil
|
||
}
|
||
|
||
func (n *Notify) next() {
|
||
if n.i+1 > int8(len(n.DelayList)) {
|
||
//当不存在下次执行,则退出定时器
|
||
n.cron.Stop()
|
||
close(n.stop)
|
||
return
|
||
}
|
||
time := "@every " + fmt.Sprintf("%ds", n.DelayList[n.i])
|
||
n.currenEntry, _ = n.cron.AddFunc(time, func() {
|
||
e := n.ResultHandle(n.DoFuc())
|
||
if n.isLoop {
|
||
//循环推送直到成功
|
||
if e {
|
||
n.stop <- struct{}{}
|
||
}
|
||
} else {
|
||
n.stop <- struct{}{}
|
||
}
|
||
})
|
||
//开启信号监听
|
||
n.registerListener()
|
||
return
|
||
}
|
||
|
||
func (n *Notify) check() error {
|
||
if n.Request == nil && n.DoFuc == nil {
|
||
return fmt.Errorf("未初始化Request")
|
||
}
|
||
if len(n.DelayList) == 0 {
|
||
return fmt.Errorf("未设置推送延迟")
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (n *Notify) registerListener() {
|
||
//注册信号监听通道
|
||
go func() {
|
||
select {
|
||
case <-n.stop:
|
||
n.cron.Remove(n.currenEntry)
|
||
n.i += 1
|
||
n.next()
|
||
}
|
||
}()
|
||
|
||
}
|